0

我想获得具有以下属性的 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>

我该如何解决这个问题?

4

1 回答 1

0

总结评论:

invalid standard deviation ==> expected: <16.73> but was: <16.72>

请注意,您很可能对此处的舍入模式有误解。

请注意,HALF_EVEN 上的 JavaDoc:

“如果舍弃分数左边的数字是奇数,则与 RoundingMode.HALF_UP 相同;如果为偶数,则与 RoundingMode.HALF_DOWN 相同”

这意味着像 16.725 这样的数字将向下取整而不是向上取整,因此使用 HALF_EVEN 的结果将为 16.72。

如何将 95 (BigDecimal) 转换为 95.00 ?

从数字的角度来看,95 和 95.00 之间没有区别,因为尾随零与前导零一样微不足道。从这个意义上说,即使 0095.0000 也是相同的数值。

当您处理 BigDecimal 时,您的第一个目标通常是进行计算,从而获得不受“任意”精度问题影响的数值(不支持不确定精度,但可以将其设置为固定值)并且是尽可能准确。

因此,如果您从数字 95、95.0 甚至字符串“95.00”创建 BigDecimal,它们将具有相同的值。

然而,它们并不相等,因为数字内部也有一个刻度,即 95 和 95.0 通常在内部表示为整数 95 和刻度 0,这意味着不必移动小数点。另一方面"95.00",将表示为数字 9500 和 2 的比例,这意味着要获得实际数字,您需要将小数点向左移动 2 位。

话虽这么说,如果您想检查 BigDecimals 是否相等,请不要使用equals(),因为这也考虑了比例,但使用compareTo() == 0它只会比较数值。

我正在开发支付系统,即使数字是 95,我也需要返回点后 2 位数的数字。

一般来说,这更像是一个格式问题。只要计算正确,系统的用户并不关心内部有多少小数位。当您需要向用户显示一个数字时,您需要将其转换为字符串,这就是格式化开始的地方。

要生成格式良好的字符串,您可以使用任何基于java.utilFormatter例如的方法String.format(printf("%.2f", bigDecimal);

最后,有一种方法可以将输出实际更改BigDecimal.toString()为 95.00,但我不建议将其用于此目的:try new BigDecimal(95).setScale(2).toString()

相反,将输出格式化为您需要的小数位数,并使用setScale()仅正确舍入之类的方法,例如,如果您想四舍五入为 2 个小数位数,请尝试new BigDecimal(16.725).setScale(2, RoundingMode.HALF_UP)

于 2021-07-08T06:42:52.127 回答