- 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/
这个问题已经有答案了: Why do immutable classes provide mutators? (1 个回答) 已关闭 8 年前。 感谢您的建议。 这是为什么: import java.
在我当前使用SpriteKit的项目中,我有一堆需要在不同时间分别放大和缩小的Sprite。问题在于,当我缩放节点时,物理主体不会随之缩放,因此会破坏物理状态。这是我为解决这个问题而编写的一个小示例:
有人请告诉我我犯的错误: 我的号码:225.0453,内部保存有 4 位数字。这是一个美元货币数字,我想要 pretty-print 来显示。我用RoundingMode.HALF_EVEN 由于美元
我正在这样做: (obj.getValue().divide(weight)).setScale(3, RoundingMode.HALF_DOWN) 我收到此错误: java.lang.Arithm
此代码在我提到的 setScale(); 行给我一个错误它给我一个错误,说需要四舍五入。我正在尝试制作一个应用程序,它将接受 cp 和 sp,然后根据利润/损失找到利润/损失百分比。有人可以帮我处理
setValue(BigDecimal value) { this.value=value; this.value.setScale(8, RoundingMode.H
考虑这段代码: import java.math.BigDecimal; import java.math.RoundingMode; public class RoundingTests {
任何人都可以帮助我使用 BigDecimal,我是新手 我想将 24.33 舍入到 25.00 我只需要执行天花板操作 所以我做了这样的事情 BigDecimal amount = new BigDe
你好,我正在尝试使用 libGDX 制作一个简单的游戏,但我在使用 sprite 类时遇到了一些问题,这是我的代码: package com.carebearer; import com.badlog
我正在使用 libgdx,但使用 BitmapFont 类给了我一个非常巨大的文本。即使我将比例设置为非常小的值(0.1f),字体仍然会以巨大的尺寸呈现。 Libgdx 文档没有解释我应该使用的正常值
我正在关注这个 YouTube 系列节目,您可以在其中学习如何在出现错误时编写游戏程序,因此我修复了该错误,但这导致了另一个错误。而且我很确定我所做的与 YouTuber 完全一样。 所以,如果您知道
我们有以下代码: BigDecimal net = price .divide(taxCumulative, RoundingMode.HALF_UP) .setScale(2, BigDecimal
我目前正在尝试缩放字体,但收到错误消息“方法 setScale(float, float) 未定义 BitmapFont 类型”这是我收到错误的代码部分,特别是在第 2 行和第 4 行。 fo
如果我使用 KineticJS 设置比例/缩放,我会收到一个奇怪的错误。出现随机线条。 EDIT1:好的。看起来如果我将 scaleRate 设置为 0.25、0.125、0.0625 等,它就可以工
public class Dummy { public static void main(String args[]) { String x = "1.234.567,89 E
我正在尝试使用以下命令指定BigDecimal值的精度:new BigDecimal(12.99).setScale(2, BigDecimal.ROUND_HALF_EVEN。但是,编译器告诉我se
我正在尝试在用户获得额外生命时缩放 Sprite 并在 1 或 2 秒后将其设置回正常值。 我有这个: if (_score == 2) { _life = _life + 1; st
在我的 Android 应用程序中,我加载了一张图片。用户可以使用这张图片放大、缩小和前后移动它。目前我一次只能让一个人工作。 经过大量测试后,我确定我所说的第二个是有效的。 matrix.setSc
我将以下代码与 half_even 舍入模式的 java BigDecimal setScale 方法一起使用,并得到以下结果。 new BigDecimal(1.115).setScale(2, R
为了对数字进行四舍五入,我使用以下代码: public static roundBd(BigDecimal bd){ BigDecimal result1 = bd.setScale(0, Rou
我是一名优秀的程序员,十分优秀!