gpt4 book ai didi

java - 大十进制 : HALF_UP rounding with setScale

转载 作者:搜寻专家 更新时间:2023-11-01 02:57:24 24 4
gpt4 key购买 nike

我们有以下代码:

BigDecimal net = price
.divide(taxCumulative, RoundingMode.HALF_UP)
.setScale(2, BigDecimal.ROUND_UP);

我们正在对此进行单元测试,并根据我们是否在测试类上使用 @Transactional 获得不同的结果。

我只是想知道我们是否应该期望 HALF_UP 的应用与 setScale 一起或在它之前考虑。

例如:

说:

价格 = 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。但是 a 也是有道理的。

有什么想法吗?

更新:

按照@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。

最佳答案

它似乎会受到影响,具体取决于您构建 BigDecimal

的方式

查看关于 public BigDecimal(double val) 的构造说明

1.- The results of this constructor can be somewhat unpredictable. One might assume that writing new BigDecimal(0.1) in Java creates a BigDecimal which is exactly equal to 0.1 (an unscaled value of 1, with a scale of 1), but it is actually equal to 0.1000000000000000055511151231257827021181583404541015625. This is because 0.1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the value that is being passed in to the constructor is not exactly equal to 0.1, appearances notwithstanding.

2.-The String constructor, on the other hand, is perfectly predictable: writing new BigDecimal("0.1") creates a BigDecimal which is exactly equal to 0.1, as one would expect. Therefore, it is generally recommended that the String constructor be used in preference to this one.

3.-When a double must be used as a source for a BigDecimal, note that this constructor provides an exact conversion; it does not give the same result as converting the double to a String using the Double.toString(double) method and then using the BigDecimal(String) constructor. To get that result, use the static valueOf(double) method.

关于java - 大十进制 : HALF_UP rounding with setScale,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51618140/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com