• new BigDecimal(0.01) 与 new BigDecimal(String.valueOf(0.01))的区别 (转)


    转自:http://blog.csdn.net/major1985/article/details/50210293

    一般我们使用BigDecimal进行比较精密的计算,我这里计算金额。注意使用double构造器的本质与String构造的本质,避免造成问题。

    我这里出现的问题是金额总是多了0.01

    问题出现在这段代码:

    if(valueDiffDays > 0){
                logger.info("该账单{}需要缴纳{}天利息",loanBillLogDO.getBillSeqNo(),valueDiffDays);
                interestAmt = repayAmt * interestDayRate * valueDiffDays;
                loanBillLogDO.setInterestAmt(new BigDecimal(interestAmt).setScale(2, RoundingMode.UP));
    
            }

    应该是0.80的总是变成0.81,进行断点调试发现interestAmt的值是0.8.

    进行测试:

     @Test
        public void testBigDecimalMode(){
            double dayRate = 0.08;
            double amt = 1000;
            int diff = 1;
    
            double interestAmt = amt*dayRate/100*diff;
            BigDecimal tInterestAmt = new BigDecimal(interestAmt).setScale(2 , RoundingMode.UP);
            System.out.println(interestAmt);
            System.out.println(tInterestAmt);
    
            BigDecimal a = new BigDecimal("0.8");
            System.out.println(a.setScale(2, RoundingMode.UP));
            BigDecimal b = new BigDecimal(0.8);
            System.out.println(b.setScale(2 , RoundingMode.UP));
    //        loanBillLogDO.setInterestAmt(new BigDecimal(interestAmt).setScale(2, RoundingMode.UP));
        }

    基本确定BigDecimal的double构造存在问题,String构造不存在问题。

    api说明:

     

    BigDecimal
    
    public BigDecimal(String val)
    将 BigDecimal 的字符串表示形式转换为 BigDecimal。字符串表示形式由可选符号 '+' ( 'u002B') 或 '-' ( 'u002D') 组成,后跟零或多个十进制数字(“整数”)的序列,可以选择后跟一个小数,也可以选择后跟一个指数。
    该小数由小数点以及后跟的零或更多十进制数字组成。字符串必须至少包含整数或小数部分中的一个数字。由符号、整数和小数部分组成的数字称为有效位数。
    
    指数由字符 'e''u0065') 或 'E' ('u0045') 以及后跟的一个或多个十进制数字组成。指数的值必须位于 Integer.MAX_VALUE (Integer.MIN_VALUE+1) 和 Integer.MAX_VALUE(包括)之间。
    
    更正式地说,以下语法描述了此构造方法接受的字符串:
    
    BigDecimalString:
    Signopt Significand Exponentopt
    Sign:
    +
    -
    Significand:
    IntegerPart . FractionPartopt
    . FractionPart
    IntegerPart
    IntegerPart:
    Digits
    FractionPart:
    Digits
    Exponent:
    ExponentIndicator SignedInteger
    ExponentIndicator:
    e
    E
    SignedInteger:
    Signopt Digits
    Digits:
    Digit
    Digits Digit
    Digit:
    Character.isDigit(char) 对其返回 true 的任何字符,如 012……
    返回的 BigDecimal 的标度将是小数部分中的数字位数,如果该字符串不包含小数点,则标度为零,这取决于对指数的调整;如果字符串包含一个指数,则从标度减去该指数。得到的标度值必须位于 Integer.MIN_VALUE 和 Integer.MAX_VALUE(包括)之间。
    
    Character.digit(char, int) 集提供从字符到数字的映射,以转换成基数 10。该字符串不能包含任何额外字符(例如,空白)。
    
    示例:
    返回的 BigDecimal 的值等于有效位数 × 10 指数。对于左边的每个字符串,得到的表示形式 [BigInteger, scale] 显示在右边。
    
     "0"            [0,0]
     "0.00"         [0,2]
     "123"          [123,0]
     "-123"         [-123,0]
     "1.23E3"       [123,-1]
     "1.23E+3"      [123,-1]
     "12.3E+7"      [123,-6]
     "12.0"         [120,1]
     "12.3"         [123,1]
     "0.00123"      [123,5]
     "-1.23E-12"    [-123,14]
     "1234.5E-4"    [12345,5]
     "0E+7"         [0,-7]
     "-0"           [0,0]
     
    注:对于不是 floatdouble NaN 和 ±Infinity 的值,此构造方法与 Float.toString(float) 和 Double.toString(double) 返回的值兼容。这通常是将 floatdouble 转换为 BigDecimal 的首选方法,因为它不会遇到 BigDecimal(double) 构造方法的不可预知问题。
    
    参数:
    val - BigDecimal 的字符串表示形式。
    抛出:
    NumberFormatException - 如果 val 不是 BigDecimal 的有效表示形式。

  • 相关阅读:
    IT项目管理之系统规划
    项目经理感悟之风险管理
    IT项目管理之系统设计
    IT项目管理之系统验收
    IT项目管理之系统测试
    IT项目管理之系统部署
    大中小型项目管理的区别
    算法评测
    IT项目管理那些事儿
    应用算法的实际情况——简单就是美
  • 原文地址:https://www.cnblogs.com/aigeileshei/p/6860909.html
Copyright © 2020-2023  润新知