22.用整数类型处理货币

2018-03-08  本文已影响0人  木心若素

我们知道在计算机中存储小数是通过整数部分正常的取其补码,但是小数部分是通过乘2取整直到余0为止的方式去表示的。
也就是说浮点数8个字节(64个bit)的长度,如果其小数部分无限循环的话,最后表示出来的数据也只能无限接近这个准确值。例如用浮点数表示1/3

比如我现在去楼下超市买了一瓶1.9的矿泉水。我拿了一张5元的人民币,理论上找回金额的代码应该这么写的

  public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        System.out.print("请输入多个数字判断奇偶:");
        while(input.hasNextInt()) {
            System.out.println(10.00-9.60);
        }
    }

可是。。。让人很失望!!
运行结果:
  0.40000000000000036

命运似乎开了天大的玩笑,不过想想也对呀! 0.4本来就是用二进制无法准确表示的的呀,乘2取余取到0为止对0.4来说循环是根本停不来。所以才会出现这种情况。
我们可能会想到这样取整:

  public static void main(String[] args) {
        NumberFormat format = new DecimalFormat("#.##");
        System.out.println(format.format(10.00-9.60));
    }

查看运行结果等于0.4,貌似解决了问题,然而对于我们当前场景,你可能觉得这点误差没啥,但是如果在金融行业,这点误差可能带来无法估量的损失。解决方法有如下:

  1. 其实Java中有专门弥补浮点数无法精确计算缺憾而设计的类BigDecimal,它提供了常用的数学算法加减乘除,特别是和数据库的Decimal类型字段映射时,BigDecimal是最佳解决方案。

*2.当然在一些要求不是很高的行业,比如超市等零售行业,我们一般采用将小数先扩大,在进行运算,最后缩小回去就可以,这种方法简单快速。

上一篇下一篇

猜你喜欢

热点阅读