我们有以下代码:
BigDecimal net = price
.divide(taxCumulative, RoundingMode.HALF_UP)
.setScale(2, BigDecimal.ROUND_UP);
我们是单元测试这个并得到不同的结果取决于我们是否在测试类上使用 @Transactional
.
我只是想知道我们是否应该期望 HALF_UP
的应用与 setScale
或之前一起考虑 .
例如:
比如说 :
price = 4.00
taxCumulative = 1.20
你期望计算如下:
a) 4.00 / 1.20 = 3.33333333... --> HALF_UP --> 3 --> setScale --> 3
要么
b) 4.00 / 1.20 = 3.33333333... --> HALF_UP with setScale 2 --> 3.33
就像我说的那样,我们对这段代码进行了单元测试,当我们有 @Transactional
时,它们的行为会有所不同 . 所以我们无法得出结论 . 在现实世界中,结果是b . 但是也有道理 .
有什么想法吗?
UPDATE :
按照@Mark的建议,我在 Spring 天环境之外创建了一个测试 . (但我想没有办法像codepen一样在网上分享它) .
package com.company;
import java.math.BigDecimal;
import java.math.RoundingMode;
public class Main {
public static void main(String[] args) {
BigDecimal price = new BigDecimal("4.00");
BigDecimal taxCumulative = new BigDecimal("1.20");
BigDecimal net = price.divide(taxCumulative, RoundingMode.HALF_UP).setScale(2, BigDecimal.ROUND_UP);
System.out.println("With String constructor, the net = " + net.toString());
// prints 3.33
price = new BigDecimal(4.00);
taxCumulative = new BigDecimal(1.20);
net = price.divide(taxCumulative, RoundingMode.HALF_UP).setScale(2, BigDecimal.ROUND_UP);
System.out.println("With doubles, the net = " + net.toString());
// prints 3.00
}
}
因此,正如@gtgaxiola所指出的,String构造函数有所不同 .
至于使用setScale进行除法运算的问题 . 我做了一些测试:
price = new BigDecimal("4.000000");
taxCumulative = new BigDecimal("1.2000000");
net = price.divide(taxCumulative, RoundingMode.HALF_UP).setScale(2, BigDecimal.ROUND_UP);
// 3.34
price = new BigDecimal("4.000000");
taxCumulative = new BigDecimal("1.2000000");
net = price.divide(taxCumulative, RoundingMode.HALF_UP);
// 3.333333
price = new BigDecimal("4");
taxCumulative = new BigDecimal("1.2");
net = price.divide(taxCumulative, RoundingMode.HALF_UP);
// 3
因此,结果在很大程度上取决于字符串输入的精度,并且在除法产生其结果之后应用setScale .
1 回答
它看起来会受到影响,具体取决于你如何构建
BigDecimal
检查public BigDecimal(double val)上的构造函数说明