BigDecimal在除法时丢失精度



考虑以下BigDecimals

BigDecimal("6.0000").precision() // = 5
BigDecimal("0.20000").precision() // = 5

当你划分这些大小数:

BigDecimal("6.0000").divide(BigDecimal("0.20000")) // = 3E+1

BigDecimal("6.0000").divide(BigDecimal("0.20000")).precision() // = 1

因此,将两个精度为5的BigDecimal除以,得到精度为1的BigDecial。即使通过提供MathContext将精度明确设置为5,结果也是一样的:

BigDecimal("6.0000").divide(BigDecimal("0.20000"), MathContext(5, RoundingMode.HALF_UP)) // = 3E+1

另一方面,当我设置scale时,我最终会得到更高精度的

BigDecimal("6.0000").divide(BigDecimal("0.20000"), 5, RoundingMode.HALF_UP).precision() // = 7

在执行上述除法时,有没有办法保持精度?这是否只能通过指定scale而不是precision来实现?

关于scale,javadoc指出首选的划分比例是dividend.scale() - divisor.scale()。然而,它也指出

这些刻度是返回精确算术结果的方法使用的刻度;除了精确除法可能必须使用更大的刻度,因为精确结果可能具有更多的数字。例如,1/32是0.03125。

上述情况不是这样吗,因为确切的结果需要更多的数字?

在您的情况下,这并不重要,因为结果是精确的。如果您需要具体的精度(可能用于解析(,请在末尾使用setScale

如果函数需要失去精度才能得到结果(例如,因为1除以3(,除法会引发异常(在使用divide函数的情况下,因为Kotlindiv运算符会对结果进行四舍五入,从而失去精度(。这就是为什么在除法时最好自己设置精度和舍入模式。

import java.math.BigDecimal
import java.math.RoundingMode.HALF_EVEN
fun main() {
val a = BigDecimal("1.0")
val b = BigDecimal("3.0")
val c = a.divide(b, 10, HALF_EVEN)
println(c) // 0.3333333333
println(c.precision()) // 10
}

最新更新