zoukankan      html  css  js  c++  java
  • BigDecimal精度问题

    介绍

      1.商业计算使用BigDecimal。
      2.使用参数为String的构造函数。
      3.BigDecimal都是不可变的,每一步的运算时,都会产生一个新的对象。所以在做加减乘除后千万要保存操作后的值。

    案例

      代码1:

    public class Test001 {
    	public static void main(String args[]) {
    		BigDecimal a = new BigDecimal(1.5);
    		BigDecimal a1 = new BigDecimal(329.530);
    		System.out.println(a.multiply(a1).setScale(2, BigDecimal.ROUND_HALF_UP));
    	}
    }
    

      输出:

    494.29
    

      代码2:

    public class Test001 {
    	public static void main(String args[]) {
    		BigDecimal a = new BigDecimal("1.5");
    	  BigDecimal a1 = new BigDecimal("329.530");
    		System.out.println(a.multiply(a1).setScale(2, BigDecimal.ROUND_HALF_UP));
    	}
    }
    

      输出:

    494.30
    

    计算器输出结果:

    489.30
    

      原因解析:
      JDK的描述:参数为dubbo的构造方法的结果具有一定的不可预知性,认为java在写入new BigDecimal(0.1)中这个0.1不是标准的0.1可能是一个无限趋近于0.1的一个小数,虽然表面上等于他。

    源码

        public BigDecimal multiply(BigDecimal multiplicand) {
            int productScale = checkScale((long) scale + multiplicand.scale);
            if (this.intCompact != INFLATED) {
                if ((multiplicand.intCompact != INFLATED)) {
                    return multiply(this.intCompact, multiplicand.intCompact, productScale);
                } else {
                    return multiply(this.intCompact, multiplicand.intVal, productScale);
                }
            } else {
                if ((multiplicand.intCompact != INFLATED)) {
                    return multiply(multiplicand.intCompact, this.intVal, productScale);
                } else {
                    return multiply(this.intVal, multiplicand.intVal, productScale);
                }
            }
        }
    

      在这个地方就是判断是不是字符串的,这个this.intCompact 是获取到参数的整数值,如果获取到时一大串数字,那就是dubbo参数传进来的,这里进行判断,从而获取到不同的值。进入到不同的方法进行运算。其实运算原理大致说下,小数转换为整数计算,最后除以10的n次方即可。

  • 相关阅读:
    相机用的 SD Card 锁Lock 烂掉了,无法正常写入
    Cannon 60D 电池卡在电池槽了,拔不出来怎么办?
    免费好用的 Apple 工具(Windows 适用)
    𠝹 (界刂) 呢個字點打?
    学校或公司转ISP -boardband (上网公司)注意事项记录
    iis站点添加.asmx的映射
    跨页面传参
    setTimeout和setInterval
    鼠标获取屏幕上的固定点位置坐标
    把完整字符串分割为字符串数组
  • 原文地址:https://www.cnblogs.com/donghang/p/9233656.html
Copyright © 2011-2022 走看看