第二章 Java浮点数精确计算
1、实际意义
在实际开发中,如果需要进行float或double的精确计算(尤其是财务计算),直接使用float或double是不行的(具体的例子看下边的代码的main方法的测试结果),需要使用BigDecimal。
2、代码
package com.xxx.util; import java.math.BigDecimal; /**
* 浮点数精准算法
*/
public class BigDecimalArithUtil { private static final int DIV_SCALE = 10;//除法精度(除不尽时保留10为小数) /** 小数精确加法 */
public static double add(double d1,double d2)
{
BigDecimal bd1 = BigDecimal.valueOf(d1);
BigDecimal bd2 = BigDecimal.valueOf(d2);
return bd1.add(bd2).doubleValue();
} /** 小数精确减法 */
public static double sub(double d1,double d2)
{
BigDecimal bd1 = BigDecimal.valueOf(d1);
BigDecimal bd2 = BigDecimal.valueOf(d2);
return bd1.subtract(bd2).doubleValue();
} /** 小数精确乘法 */
public static double mul(double d1,double d2)
{
BigDecimal bd1 = BigDecimal.valueOf(d1);
BigDecimal bd2 = BigDecimal.valueOf(d2);
return bd1.multiply(bd2).doubleValue();
} /** 小数精确除法 */
public static double div(double d1,double d2)
{
BigDecimal bd1 = BigDecimal.valueOf(d1);
BigDecimal bd2 = BigDecimal.valueOf(d2);
/*
* 当除不尽时,以四舍五入的方式(关于除不尽后的值的处理方式有很多种)保留小数点后10位小数
*/
return bd1.divide(bd2, DIV_SCALE, BigDecimal.ROUND_HALF_UP).doubleValue();
} public static void main(String[] args)
{
//测试加法
System.out.println("0.05+0.01="+BigDecimalArithUtil.add(0.05,0.01));
System.out.println("0.05+0.01="+(0.05+0.01));
//测试减法
System.out.println("1.0-0.42="+BigDecimalArithUtil.sub(1.0,0.42));
System.out.println("1.0-0.42="+(1.0-0.42));
//测试乘法
System.out.println("4.015*100="+BigDecimalArithUtil.mul(4.015,100));
System.out.println("4.015*100="+(4.015*100));
//测试除法
System.out.println("123.3/100="+BigDecimalArithUtil.div(123.3,100));
System.out.println("123.3/100="+(123.3/100));
} }
3、注意点
- 上边的程序我用的是BigDecimal.valueOf(double x)来将double型的x封装成BigDecimal,查看源码如下:
/**
* 注意:这通常是将double和float转换为一个BigDecimal的最好方式
*/
public static BigDecimal valueOf(double val) {
return new BigDecimal(Double.toString(val));
}在这里直接先将double转换为了String,然后使用如下构造方法再将String转换为BigDecimal
public BigDecimal(String val)
这是最好的做法。如果使用的是直接将double或float转换为BigDecimal的方式,也就是说使用的如下构造器,那么将可能得不到精确结果。(看注释)这一点可以用10.02*10.02来证明。
/**
* 注意:The results of this constructor can be somewhat unpredictable.
* 该构造器的结果有时是不准确的
*/
public BigDecimal(double val) - 在实际使用中还可能使用int和long来进行浮点数的精确计算(具体做法:将浮点数先乘以相应的倍数转化为int(<=9位十进制数)或long(<=18位十进制数),计算之后再除以之前的倍数,得出结果),而且该种方式的性能会更高,具体的int、long和BigDecimal各自的使用看《Effective Java(第二版)》第48条。
- 需要指出的是,在实际开发中,BigDecimal的性能差的问题基本可以忽略,是浮点数精确计算的首选,而且根据上一条来看,如果将浮点数转化后的整数大于18位的话,也必须用BigDecimal
第二章 Java浮点数精确计算的更多相关文章
- Java浮点数精确计算
BigDecimal是Java提供的一个不变的.任意精度的有符号十进制数对象.
- java面向对象编程——第二章 java基础语法
第二章 java基础语法 1. java关键字 abstract boolean break byte case catch char class const continue default do ...
- 《深入理解java虚拟机》第二章 Java内存区域与内存溢出异常
第二章 Java内存区域与内存溢出异常 2.2 运行时数据区域
- 第二章Java内存区域与内存溢出异常
第二章 Java内存区域与内存溢出异常 一.概述 对与Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要为每个new操作去写delete/free代码,不容易出现内存泄露和内存溢出问 题, ...
- 虚拟机--第二章java内存区域与内存溢出异常--(抄书)
这是本人阅读周志明老师的<深入理解Java虚拟机>第二版抄写的,有很多省略,不适合直接阅读,需要阅读请出门左转淘宝,右转京东,支持周老师(侵权请联系删除) 第二章java内存区域与内存溢出 ...
- 浮点数运算结果不精确,以及用String来构造BigDecimal进行浮点数精确计算
1.浮点数运算结果不精确 先看如下代码 System.out.println(1.0 - 0.8); System.out.println(0.2 + 0.1); System.out.println ...
- java 小数精确计算
小数精确计算 System.out.println(2.00 -1.10);//0.8999999999999999 上面的计算出的结果不是 0.9,而是一连串的小数.问题在于1.1这个数字不能被精确 ...
- JAVA中精确计算金额BigDecimal
package com.chauvet.utils; import java.math.BigDecimal; import java.text.DecimalFormat; import java. ...
- 第二章 Java 基本语法1
2.1关键字 1.定义:被Java语言赋予了特殊含义,用做专门用途的字符串(单词). 2.特点:关键字中所有字母都是小写字母. 3.分类: 用于定义数据类型的关键字:byte.short.int.lo ...
随机推荐
- 20169211 《Linux内核原理与分析》第十一周作业
SET-UID程序漏洞实验 一.实验简介 Set-UID 是Unix系统中的一个重要的安全机制.当一个Set-UID程序运行的时候,它被假设为具有拥有者的权限.例如,如果程序的拥有者是root,那么任 ...
- web到service简单原理例子
这是目前的理解 附上服务端源码 package com.lsw.server; import java.io.*; import java.net.*; import java.util.HashMa ...
- CSUOJ 1271 Brackets Sequence 括号匹配
Description ]. Output For each test case, print how many places there are, into which you insert a ' ...
- SD卡分区查看(u-boot下)
可以在U-Boot的命令行中通过命令查看MMC的信息,如: U-Boot# mmc list OMAP SD/MMC: 0 OMAP SD/MMC: 1 列出mmc设备 U-Boot# mmc dev ...
- 怎么处理stdClass::__set_state
处理后 处理方法 function object2array_pre(&$object) { if (is_object($object)) { $arr = (array)($object) ...
- BZOJ.4516.[SCOI2016]幸运数字(线性基 点分治)
题目链接 线性基可以\(O(log^2)\)暴力合并.又是树上路径问题,考虑点分治. 对于每个点i求解 LCA(u,v)==i 时的询问(u,v),只需求出这个点到其它点的线性基后,暴力合并. LCA ...
- 【spfa】【动态规划】zoj3847 Collect Chars
转载自:http://blog.csdn.net/madaidao/article/details/42616743 Collect Chars Time Limit: 2 Seconds ...
- bzoj 3545/3551: [ONTAK2010]Peaks -- 主席树,最小生成树,倍增
3545: [ONTAK2010]Peaks Time Limit: 10 Sec Memory Limit: 128 MB Description 在Bytemountains有N座山峰,每座山峰 ...
- HDU 4727 The Number Off of FFF (水题)
The Number Off of FFF Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- 配置tomcat让shtml嵌套文件显示
之前,我知道tomcat可以直接解析shtml文件,在浏览器中显示效果来,后来由于需求发生改变,比如说 在做静态化生成的时候一个网站的头部和底部都是一样的,如果每个页面都生成一次,显然很浪费时间,所有 ...