概述
在java.math包中有个BigDecimal类,通过这个类可以进行精确计算. 我们知道BigDecimal有个setScale(int 精度,int 舍入模式)方法,随之而来问题出现了,当运行如下代码时:
却惊奇地打印出结果:
0.82
Oh My God,对0.825进行小数点后保留2位有效数字,四舍五入后结果应该是:0.83。为什么打印结果是0.82?
没错BigDecimal(double val)这个构造器欺骗了我们,它使用了0.825的近似值(0.8249999999999……)来构造BigDecimal。
为什么会这样?
原来JAVA存储浮点数(float、double)时,使用的是IEEE754标准,每个浮点数使用的是 符号位、阶码、尾数来表示:
````````符号位 阶码 尾数 长度
float 1 8 23 32
double 1 11 52 64
通过这种方法保存在计算机里面的浮点数,实际上是它的近似值。举例说明问题:
定义一个double 38414.4,将它转换为16进制。我们先计算整数部分38414等于960E。小数处理:0.4=0*0.5+0.25*1+0.0625*0+……,实际上我们永远计算不完。
结论:当我们定义一个浮点数时,请告诉自己,我们定义只不过是这个浮点数的近似值,即0.825!=0.825。
为了避免这个问题,我们应该使用如下方法:
使用BigDecimal(String val)构造器,这段代码运行的结果是:0.83
由此可见BigDecimal(double val)这个构造器完全就是一个陷阱。
最后
以上就是爱笑荔枝为你收集整理的JAVA-精确计算时的陷阱的全部内容,希望文章能够帮你解决JAVA-精确计算时的陷阱所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复