大数乘法
BigDecimal Multiplication
我尝试将两个 BigDecimal
值与 multiply
方法相乘,如下所示,
BigDecimal dur = BigDecimal.valueOf(60/1.1);
BigDecimal bal = BigDecimal.valueOf(1.1);
BigDecimal ans = dur.multiply(bal);
System.out.println("Ans:"+ans);
我将 ans 排除为 60
。但我明白了,
Ans:59.999999999999994
为什么会这样,我们该如何解决。
您需要使用 String
构造函数而不是 double
构造函数。 60/1.1
没有 String
表示,因为它是 54.(54).
BigDecimal
不支持不能写成定长小数的数字。
来自 BigDecimal
Javadoc:
In the case of divide, the exact quotient could have an infinitely long decimal expansion; for example, 1 divided by 3. If the quotient has a nonterminating decimal expansion and the operation is specified to return an exact result, an ArithmeticException is thrown. Otherwise, the exact result of the division is returned, as done for other operations.
问题是您的值无法在 double
中表示,但也无法在 BigDecimal 中表示,因此您必须应用合理的舍入以获得预期的解决方案。
double d = 60 / 1.1 * 1.1;
System.out.println("double without rounding: " + d);
System.out.printf("double With rounding %.2f%n", d);
BigDecimal bd = BigDecimal.valueOf(60).divide(BigDecimal.valueOf(1.1), 9, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(1.1));
System.out.println("BigDecimal without rounding: " + bd);
System.out.printf("BigDecimal with rounding %.2f%n", bd);
// or
bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("BigDecimal with rounding: " + bd);
打印
double without rounding: 60.0
double With rounding 60.00
BigDecimal without rounding: 59.9999999995
BigDecimal with rounding 60.00
BigDecimal with rounding: 60.00
注意:double
恰好对这些值进行了正确舍入并给出了正确答案。但是,选择不同的组合,它将是不正确的。例如54.545454545454545 * 1.1 => 60.00000000000001
我尝试将两个 BigDecimal
值与 multiply
方法相乘,如下所示,
BigDecimal dur = BigDecimal.valueOf(60/1.1);
BigDecimal bal = BigDecimal.valueOf(1.1);
BigDecimal ans = dur.multiply(bal);
System.out.println("Ans:"+ans);
我将 ans 排除为 60
。但我明白了,
Ans:59.999999999999994
为什么会这样,我们该如何解决。
您需要使用 String
构造函数而不是 double
构造函数。 60/1.1
没有 String
表示,因为它是 54.(54).
BigDecimal
不支持不能写成定长小数的数字。
来自 BigDecimal
Javadoc:
In the case of divide, the exact quotient could have an infinitely long decimal expansion; for example, 1 divided by 3. If the quotient has a nonterminating decimal expansion and the operation is specified to return an exact result, an ArithmeticException is thrown. Otherwise, the exact result of the division is returned, as done for other operations.
问题是您的值无法在 double
中表示,但也无法在 BigDecimal 中表示,因此您必须应用合理的舍入以获得预期的解决方案。
double d = 60 / 1.1 * 1.1;
System.out.println("double without rounding: " + d);
System.out.printf("double With rounding %.2f%n", d);
BigDecimal bd = BigDecimal.valueOf(60).divide(BigDecimal.valueOf(1.1), 9, BigDecimal.ROUND_HALF_UP).multiply(BigDecimal.valueOf(1.1));
System.out.println("BigDecimal without rounding: " + bd);
System.out.printf("BigDecimal with rounding %.2f%n", bd);
// or
bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
System.out.println("BigDecimal with rounding: " + bd);
打印
double without rounding: 60.0
double With rounding 60.00
BigDecimal without rounding: 59.9999999995
BigDecimal with rounding 60.00
BigDecimal with rounding: 60.00
注意:double
恰好对这些值进行了正确舍入并给出了正确答案。但是,选择不同的组合,它将是不正确的。例如54.545454545454545 * 1.1 => 60.00000000000001