• Effective Java 之-----精确的答案与double&float


    题目: 假设你口袋里有1$,看到货架上有一排美味的糖果,标价分别为0.10$,0.20$,0.30$...1$,你打算从标价为0.10$的糖果开始买起,每种买一颗,一直到不能支付货架上下一种价格的糖果为止,那么可以买多少颗糖果?还可以找回多少零钱?

    使用double的程序如下:

    double funds = 1.00;
    int itemsBought = 0;
    for(double price=.10;funds>=price;price+=.10){
          funds -= price;
          itemsBought++;
    }
    System.out.println(itemsBought+" items bought.");
    System.out.println("change:$"+funds);
    

    返回结果如下:
    3 items bought.
    change:$0.3999999999999999

    这个答案是不正确的,解决方案是使用BigDecimal,int或者long进行货币计算

    使用BigDecimal的程序如下:

    final BigDecimal TEN_CENTS = new BigDecimal(".10");
    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);
    

    返回结果如下:
    4 items bought.
    change:$0

    这个结果是正确的。

    使用int的程序如下(需将1.00$先转换为100cents):

    int itemsBought = 0;
    int funds = 100;
    for(int price=10;funds>=price;price+=10){
          funds -= price;
          itemsBought++;
    }
    System.out.println(itemsBought+" items bought.");
    System.out.println("change:$"+funds);

    返回结果如下:
    4 items bought.
    change:$0

    这个结果也是正确的。

    所以:
    1)如果需要通过法定要求的舍入行为进行业务计算,使用BigDecimal是非常方便的;
    2)如果性能非常关键,而且又不介意记录十进制小数点,而且所涉及的数值又不太大,就可以使用int或long,
    3) 如果数值范围没超过9位十进制数字,就可以使用int,如果数值范围没超过18位十进制数字,可以使用long,如果数值范围超过了18位十进制数字,就必须使用BigDecimal。

  • 相关阅读:
    继承ViewGroup:重写onMeasure方法和onLayout方法
    Eclipse插件的四种安装方法
    android 多条短信息发出后的状态怎样判断
    关闭windows的自动更新
    有的放矢,用好软件开发的目标管理
    安卓打包之数字签名
    PHP+jQuery实现Ajax分页效果:jPaginate插件的应用
    使用SqlDataReader获取输出参数
    ServU服务器中文乱码问题的解决
    VPS虚拟主机与VM虚拟主机对比
  • 原文地址:https://www.cnblogs.com/hunterCecil/p/5614924.html
Copyright © 2020-2023  润新知