• 第48条:如果需要精确的答案,请避免使用float和double


    float和double主要为了科学计算和工程计算而设计,执行二进制浮点运算,这是为了在广泛的数值范围上提供较为精确的快速近似计算而精心设计的。然而,它们没有提供完全精确的结果,所以不适合用于需要精确结果的场合,尤其是货币计算。

    //假设有1.03元,花掉0.42元后
    System.out.println(1.03 - .42);//0.6100000000000001
    
    System.out.println(1.00 - 9 * .10);//0.09999999999999998

    使用舍入可以解决上面问题,但并不是所有的问题都能用舍入解决,如有1元,有0.1,0.2,0.3,一直到1元的糖果,从0.1开始买,直到不能支付为止:

    public static void main(String[] args) {
        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("Money left over: $" + funds);
    }

    结果是:

    使用BigDecimal是正确的办法:

    public static void main(String[] args) {
        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("Money left over: $" + funds);
    }

    结果是:

    使用BigDecimal的缺点是:1.与基本类型相比,不方便(需要创建BigDecimal对象);2.速度慢

    使用int或者long,取决于涉及的数值大小,同时要自己处理十进制小数,以分为单位,而不是以元为单位计算,就可以使用int来处理:

    public static void main(String[] args) {
        int itemsBought = 0;
        int funds = 100;
        for(int price = 10; funds >= price; price += 10) {
            itemsBought++;
            funds -= price;
        }
        System.out.println(itemsBought + " items bought.");
        System.out.println("Money left over: $" + funds);
    }

    结果与用BigDecimal是一样的。

    总结:对于需要精确答案的计算,不能使用float或者double,BigDecimal允许完全控制舍入,如果业务要求涉及多种舍入方式,使用BigDecimal很方便,如果性能很关键,涉及的数值不大,就可以使用int或者float,如果数值范围没有超过9位十进制数字,可以使用int,如果不超过18位数字,使用long,如果数值可能超过18位,就必须用BigDecimal。

  • 相关阅读:
    景深概念与计算
    机器视觉相关术语
    Inno Setup 怎么编译文件的版本号
    Qt 可执行程序写入版本信息
    Qt 程序默认管理员权限运行
    Inno Setup 改变默认路径
    Inno Setup 打包安装程序中让“是否创建快捷方式”默认为“打钩”的方法
    Inno Setup 如何让生成的setup.exe文件双击以管理员权限打开
    Inno Setup 打包出的安装程序以管理员身份运行
    InnoSetup 安装前卸载旧版程序
  • 原文地址:https://www.cnblogs.com/13jhzeng/p/5774815.html
Copyright © 2020-2023  润新知