如何获得bigdecimal中的精确值?

0yycz8jy  于 2021-08-25  发布在  Java
关注(0)|答案(1)|浏览(395)

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

我怎样才能解决这个问题?

enyaitl3

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)

相关问题