Kotlin BigDecimal 乘法错误结果

Kotlin BigDecimal multiplication wrong results

我需要使用 BigDecimal 进行一些计算,但我对这种行为感到有点惊讶:

val thousand = BigDecimal(1000)
val fee = BigDecimal(0.005)
println(thousand * fee)

您希望控制台包含 5 但结果是 5.000000000000000104083408558608425664715468883514404296875000

我知道我可以限制精度并使用 setScale 进行一些舍入,但真正的问题是为什么首先需要这样做。这个结果显然是错误的。

我错过了什么?

问题很可能与 fee BigDecimal 的构造有关。这是采用 double 值并将其转换为 BigDecimal。不幸的是,一些相当简单的小数不可能精确地表示为 doubles 或 floats,而这个 BigDecimal 的构造函数将把那个不精确的 double 作为它的值。

来自documentation

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.

解决这个问题的方法是使用 String 构造函数,它解决了必须“通过”a double.

转换的问题