`
liuwei1981
  • 浏览: 756525 次
  • 性别: Icon_minigender_1
  • 来自: 太原
博客专栏
F8258633-f7e0-30b8-bd3a-a0836a5f4de5
Java编程Step-by...
浏览量:157167
社区版块
存档分类
最新评论

java解惑------找零时刻(分析)

阅读更多

找零程序出错的原因在于,1.1这个数字不能被精确的表示为一个double,因此被表示为最接近它的double值。改程序从2中减去的就是这个值。遗憾的是,这个计算的结果并不是最接近0.9的double值。作为结果的double值的最短表示就是你看到的那个程序输出的可恶的数字。

并不是所有的小数都可以用二进制浮点数精确表示。如果使用的是JDK5或者更新的版本,那么您可能会受其诱惑,通过使用printf工具设置输出精度的方法改正程序:

System.out.pringln("%.2f%n"2.00-1.10");

这条语句打印的结果正确,但并不表示它就是对底层问题的通用解决方案:它使用的仍旧是二进制浮点数的double运算。浮点运算在一个范围很广的值域上提供了很好的近似,但是通常不能产生精确的结果。二进制浮点对于货币计算是非常不合适的,因为它不可能将0.1或者10的其他任何次幂,精确的表示为一个有限长度的二进制小数

 

解决该问题的一种方式就是使用某种整数类型。例如int或者long,并且以分为单位来执行计算。如果采纳了此路线,请确保改整数类型大到足以表示程序中将要用到的所有值。对该谜题来说,int就足够了。下面使用int类型,以分为单位表示货币值后重写的println语句:

 

System.out.println((200-190) + "cents");

 

 解决改问题的另一个方式就是使用执行精确小数运算的BigDecimal。它还可以通过JDBC与SQLDECIMAL类型进行互操作。这里要注意一点:一定要用BigDecimal(String)构造器,而千万不要用BigDecimal(double)。后一个构造器将用他的参数的精确值来创建一个实例。例如new BigDecimal(.1),它将返回一个BigDecimal,也即0.100000000000000055511151231257827021181583404541015625.正确使用BigDecimal,程序就可以输出我们所需要的结果0.90:

 

import java.math.BigDecimal;
public class Change{
  public static void main(String[] args){
        System.out.println(new BigDecimal("2.00").subtract(new BigDecimal("1.10")));
    }
}

在需要精确答案的地方,要避免使用float和double;对于货币运算,要使用int,long,BigDecimal。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics