• 静思
  • 吴言片语
    • 吴言
    • 片语
    • 杂七杂八
  • 死于青春
    • 一路走好
  • 乌合麒麟
  • 纪念
    • 5.12
    • 3.23
  • GitHub
    • A List of Post-mortems
    • The Art of Command Line
  • 关于
    • Privacy Policy

程序员的信仰

金鳞岂是池中物,一遇风云便化龙

HOME » 技术生活 » 误区!double类型做加减法不会有误差?

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

2010 年 8 月 25 日 @ 上午 10:36 by Jay | 被踩了 8,865 脚

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

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

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

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

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

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+字符串类型的构造器



-- EOF --
除非注明(如“转载”、“[zz]”等),本博文章皆为原创内容,转载时请注明: 「转载自程序员的信仰©」
本文链接地址:误区!double类型做加减法不会有误差?

分享

  • 点击分享到 Facebook (在新窗口中打开) Facebook
  • 点击以分享到 X(在新窗口中打开) X
  • 更多
  • 点击分享到Reddit(在新窗口中打开) Reddit
  • 点击分享到Telegram(在新窗口中打开) Telegram
  • 点击以在 Mastodon 上共享(在新窗口中打开) Mastodon

赞过:

赞 正在加载……

相关

Today on history:

【2012】Mac OS geek级问题
【2007】经典的回帖 [zz]
Posted in: 技术生活 Tagged: java, tips
← Java程序员必看电影:Java 4-ever
郭德纲道歉信,以后道歉就按这个套路上! →

android (9) apple (20) augmentum (9) Beijing (21) bt (8) career (28) coding (38) firefox (10) google (36) hibernate (11) ibm (11) iphone (10) java (93) linux (16) m$ (26) mac (58) macos (27) nazca (9) olympics (8) oo (8) playstation (10) rip (8) Shanghai (39) spring (9) tips (45) tommy emmanuel (8) ubuntu (12) usa (23) windows (9) 北航 (17) 博客 (29) 吐槽 (8) 周末 (9) 和谐社会 (26) 小资 (11) 愤青 (40) 方言 (10) 朋友 (77) 歌词 (8) 烟酒不分家 (18) 爱国 (19) 爱情 (8) 犯二 (15) 破解 (8) 足球 (11)

烫手山芋

  • 再谈苹果的输入法:这一次是靠OS X自带的输入法来翻身的~ - 被踩了 27,349 脚
  • 生活,就是一个期待跟着一个期待 - 被踩了 21,357 脚
  • 星巴克饮品缩写大全(Starbucks Drink ID Codes)[zz] - 被踩了 18,408 脚
  • 从一个全角冒号说一下我为什么不感冒iOS - 被踩了 14,316 脚
  • 有关Character.isLetter()和Character.isLetterOrDigit() - 被踩了 13,591 脚

刚拍的砖

  • leo 发表在《再谈苹果的输入法:这一次是靠OS X自带的输入法来翻身的~》
  • 花 发表在《再谈苹果的输入法:这一次是靠OS X自带的输入法来翻身的~》
  • 无名氏 发表在《从一个全角冒号说一下我为什么不感冒iOS》
  • Jay 发表在《Mac OS geek级问题》
  • Wei Wang 发表在《再谈苹果的输入法:这一次是靠OS X自带的输入法来翻身的~》

随便看看

  • 美国杂笔(一)4 年 ago
  • 上海口音的普通话是一种什么样的体验? [zz]9 年 ago
  • I'm a Google fan18 年 ago
  • 致网易《魔兽世界-大地的裂变》联合抗议书 [zz]14 年 ago
  • 《海上传奇》,喜欢上海的理由6 年 ago

文以类聚

光阴似箭

其他操作

  • 登录
  • 条目 feed
  • 评论 feed
  • WordPress.org

Copyright © 2025 程序员的信仰.

Jay's Omega WordPress Theme by Jay

 

正在加载评论...
 

    %d