误区!double类型做加减法不会有误差?

GD Star Rating
loading...

如果你跟我一样以为Java的double类型只有在作乘除法时才会出现误差,那试一下在Java里执行一下下面的代码:

  1. public static void  main(String[] args) {
  2.     System.out.println(44.42 + 710.79 + 44.42 +  88.85);
  3. }
public static void  main(String[] args) {
    System.out.println(44.42 + 710.79 + 44.42 +  88.85);
}

执行前先猜一下结果,是会输出888.48么?还是……?

建议:对于和钱有关的计算,不论加减乘除,统一使用 BigDecimal!

然而不多久之后同事告诉我另一个BigDecimal的问题,试一下下面的代码:

  1. System.out.println(new BigDecimal(0.99).setScale(2, RoundingMode.DOWN).toString());
System.out.println(new BigDecimal(0.99).setScale(2, RoundingMode.DOWN).toString());

结果是令人发指的0.98!

看了一下 BigDecimal(double)的源码,其中使用位操作分别提取了0.99浮点值的整数部分和纯小数部分,或者说是2的正数次幂和负数次幂部分。而这样提取出来的值纯小数部分本身就是近似的,与直接使用double类型没有本质区别,这是浮点表示法决定的,再经过2位截取后就产生了误差

而当使用BigDecimal(String)的构造器时得到的是精确值,因为该构造器将数字使用科学计数法表示,即 0.99表示为99*10^-2,这样做运算时先对齐至相同的整数位再进行计算

因此,对上面的补充是:如果要获取最精确的结果,请使用BD+字符串类型的构造器

原创内容,转载请注明: 转载自拈花微笑

本文链接地址: 误区!double类型做加减法不会有误差?

685

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code lang=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" extra="">

:wink: :-| :-x :twisted: :) 8-O :( :roll: :-P :oops: :-o :mrgreen: :lol: :idea: :-D :evil: :cry: 8) :arrow: :-? :?: :!:

使用新浪微博登陆

无觅相关文章插件,快速提升流量