前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一文读懂《Effective Java》第48条:如果需要精确答案,请避免使用float和double

一文读懂《Effective Java》第48条:如果需要精确答案,请避免使用float和double

作者头像
后台技术汇
发布2022-05-28 12:45:39
2190
发布2022-05-28 12:45:39
举报
文章被收录于专栏:后台技术汇

float 和 double 类型主要是为了科学计算和工程计算而设计的。他们执行二进制浮点运算,为了在广泛的数值范围上提供较为精准的快速近似计算而精心设计。

但是,两者都没有提供完全精准的结果,所以不应该用于需要精确结果的场合。

使用float或者double导致的精度丢失

下面我们通过两个例子认识,使用float和double进行货币计算时,导致的运算精度丢失。

例子一:标准输出运算结果

代码语言:javascript
复制
  private static void test3(){
    System.out.println(1.03 - 0.43);
    System.out.println(1.00 - 9 * 0.1);
  }

输出:

代码语言:javascript
复制
0.6000000000000001
0.09999999999999998

例子二:糖果购买。货架上依次有10美分、20美分、30美分、40美分等差价格递增的糖果,你手上有1美元(1美元=100美分),那么你能买多少颗糖果呢?

  • float/double计算
代码语言:javascript
复制
  private static void test4(){
    double funds = 1.00;
    int itemsBought = 0;
    for (double price = 0.10; funds >= price; price += 0.10){
      funds -= price;
      itemsBought++;
    }
    System.out.println(itemsBought + " items bought.");
    System.out.println("Change:$" + funds);
  }

输出结果:(显然不正确)

代码语言:javascript
复制
3 items bought.
Change:$0.3999999999999999
  • bigdecimal计算
代码语言:javascript
复制
  private static void test5(){
    final BigDecimal TEN_CENTS = new BigDecimal("0.1");
    int itemsBought = 0;
    BigDecimal funds = new BigDecimal("1.00");
    for (BigDecimal price = TEN_CENTS;
      funds.compareTo(price) >= 0;
      price = price.add(TEN_CENTS)){
      itemsBought++;
      funds = funds.subtract(price);
    }
    System.out.println(itemsBought + " items bought.");
    System.out.println("Change:$" + funds);
  }

输出结果:

代码语言:javascript
复制
4 items bought.
Change:$0.00

小结

float和double是没有提供完全精确的结果,所以不应该被用于要求精确结果的场合。商业计算往往要求结果精确(银行/金融/风控/支付结算等)就必须选择BigDecimal了。

BigDecimal类是 Java 在 java.math 包中提供的API类,用来对超过16位有效位的数进行精确的运算。除了复杂度设计和拓展性,里面的数学计算思维也很值得我们学习。

BigDecimal的源码剖析,可以参考公众号提供的另外一篇文章:

《一文带你读懂 BigDecimal 源码》 一枚少年郎,一文带你读懂 BigDecimal 源码

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-10-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 后台技术汇 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档