我希望获得具有以下属性的bigdecimal值:
舍入模式:半偶数
点后的位数:2
我有以下代码:
public BigDecimal standardDeviation() {
MathContext mc = new MathContext (4,RoundingMode.HALF_EVEN);
return new BigDecimal(Math.sqrt(variance().doubleValue()), mc);
}
在测试中,当我发送一些值时,我得到以下失败:
invalid standard deviation ==> expected: <16.73> but was: <16.72>
我怎样才能解决这个问题?
1条答案
按热度按时间enyaitl31#
总结评论:
invalid standard deviation ==> expected: <16.73> but was: <16.72>
请注意,您很可能对此处的舍入模式有误解。请注意,半偶数上的javadoc:
“行为与舍入模式相同。如果离散分数左侧的数字为奇数,则向上舍入一半;与roundingmode的行为相同。如果为偶数,则向下半个“
这意味着像16.725这样的数字将向下舍入,而不是向上舍入,因此使用半舍五入,即使结果是16.72。
如何将95(bigdecimal)转换为95.00?
从数值Angular 来看,95和95.00之间没有差异,因为尾随零和前导零一样不重要。从这个意义上讲,即使是0095.0000也将是相同的数值。
当您处理bigdecimal时,您的第一个目标通常是获得计算结果,因此不会出现“任意”精度问题(不支持不定精度,但可以将其设置为固定值),并且尽可能精确。
因此,如果您从数字95、95.0甚至字符串“95.00”创建一个bigdecimal,它们将具有相同的值。
但是,它们并不相等,因为在内部,数字也有一个刻度,即95和95.0通常在内部表示为整数95和刻度0,这意味着小数点不必移动。另一方面
"95.00"
将表示为数字9500和2的刻度,这意味着要获得实际数字,需要将小数点向左移动2位。也就是说,如果你想检查大小数是否相等,不要使用
equals()
因为这也考虑了规模,但使用compareTo() == 0
因为这只会比较数值。我在一个支付系统上工作,我需要返回点后有2位数字的数字,即使数字是95。
一般来说,这更像是一个格式问题。只要计算正确,系统用户不在乎内部有多少个小数位数。当您需要向用户显示一个数字时,您需要将其转换为字符串,这就是格式化的关键所在。
要生成格式良好的字符串,可以使用基于
java.utilFormatter
例如String.format(printf("%.2f", bigDecimal);
最后,有一种方法可以实际更改BigDecimal.toString()
到95.00,但我不建议为此目的使用它:试试看new BigDecimal(95).setScale(2).toString()
.相反,将输出格式化为所需的分数位数,并使用以下方法
setScale()
仅正确舍入,例如,如果要舍入到2个小数位数,请尝试new BigDecimal(16.725).setScale(2, RoundingMode.HALF_UP)