- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我们有以下代码:
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/
Stata 有一个 round() 函数。人们可以选择舍入到的单位。我想使用round(ArbitraryValue, 0.01)将任意浮点值四舍五入到小数点后两位。 Stata 的 display
四舍五入看起来很容易,但我不知道如何四舍五入。 使用这段代码: def __str__(self): return'x = %.2f,y = %.2f'%(self.x,self.y)
我发现一个很奇怪的问题,问题是PHP和Javascript中的ROUND方法计算结果不一样!? 请看下面的例子: PHP echo round(175.5); // 176 echo round(-1
让我们看一下那句令人震惊的round语句: >>> round(2.675, 2) 2.67 我知道为什么回合“失败”;这是因为 2.675 的二进制表示: >>> import decimal >>
这个问题已经有答案了: 奥 git _a (1 个回答) 已关闭 7 年前。 我发现 VBA Round 函数返回错误的结果。我找到了一个可行的替代方案,即使用 Application.Round 代
所以我正在运行 MySQL 5.1.4 版,我试图通过四舍五入的值来选择 distinct,它工作得很好,除了它把数字四舍五入,比如 12.5 到 12 而不是 13。我试过的列都是double型的。
guess = input("H or T?") def game(): num_rounds() for p1 in range(0, 2): p1 = ("H",
我了解到建议使用 BigDecimal 而不是 Float,但这要么是一个错误,要么突出了 Float 的深奥本质.似乎 Float#round(2) 对“1.015”、“1.025”和“1.035”
C# 中的 Math.Round 和 decimal.Round 函数有什么区别? 最佳答案 没有区别。 Math.Round(decimal)源代码: public static Decimal R
我注意到 Math.Round()比 Decimal.Round() 更灵活,因为它能够处理 Decimal.Round() 可以处理的所有事情,而且在给定 double 输入的情况下也可以处理同样的
我在生成的 SVG 中看到一个奇怪的渲染问题。我已经把它缩小到一个小的可重复的案例。 这呈现为 (至少在 Safari、Mac Chrome 或 Mac Firefox 中查看时)。我希望
我有以下 SQL Server 语句,我想将其转换为 c#。我知道 C# 中有一个叫做 Math.Round 的东西。我已经尝试过,但 C# 返回相同的结果 c# 返回一个 int。有关详细信息,请查
我正在使用 C# 和 SQL 中的 ROUND 函数,令人惊讶的是两者都产生了不同的结果。 在 SQL 中:ROUND(1250.00, -2) = 1300 在 C# 中 ROUND 1250 ro
我正在尝试使用 SSE(1,2,3) 指令创建类似于 std::round() 的函数,但某些值和/或逻辑运算符存在一些问题。这是我的代码: #include #include #include
jq 中的 round 函数不起作用。 $ jq '10.01 | round' jq: error: round/0 is not defined at , line 1: 10.01 | roun
我试图弄清楚如何使用 VBA 更改 Excel 中圆角矩形形状的圆度。 我首先创建圆角矩形,但此时我不确定下一步要做什么。 Set roundedRec = ws.Shapes.AddShape(ms
当我的代码运行时,我进入 2 人模式并调用函数 rounda 和 roundb,但由于某种原因它们没有响应。其他一切都正常,但我不知道出了什么问题。预先感谢您提供任何可能的建议。我的代码如下。我调用函
我从阅读中知道this Stackoverflow question编译器将查看您的数字,确定中点是偶数还是奇数,然后返回偶数。示例数字是 2.5,四舍五入为 3。我尝试了自己的小实验以查看会发生什么
这个问题在这里已经有了答案: There's a shadow on my button (3 个答案) 关闭 9 年前。 顺便说一句。它可能看起来像是关于按钮阴影问题的重复问题,但它们具有单调背景
据我了解,2.675 和 numpy.float64(2.675) 都是相同的数字。然而,round(2.675, 2) 给出 2.67,而 round(np.float64(2.675), 2) 给
我是一名优秀的程序员,十分优秀!