java.math.BigDecimal 除法不准确
java.math.BigDecimal division inaccuracy
在 Kotlin 中,BigDecimal 除法 returns 奇怪的结果。
BigDecimal(1.0) / BigDecimal(2.0)
// returns 0.0
// Just like Int(1) / Int(2) returns 0
但是:
BigDecimal(1.1) / BigDecimal(2.0)
// returns 0.55
// Just like Double(1.1) / Double(2.0) returns 0.55
那么为什么会发生这种情况,我如何在不使用 divide()
给出比例参数的情况下使用 BigDecimal 使 1.0 / 2.0
returns 0.5?
更新:
完整代码如下:
Welcome to Kotlin version 1.2.41 (JRE 1.8.0_172-b11)
Type :help for help, :quit for quit
>>> import java.math.BigDecimal
>>> BigDecimal(1.0) / BigDecimal(2.0)
0
>>> BigDecimal(1.1) / BigDecimal(2.0)
0.550000000000000044408920985006261616945266723632812
更新 2:
根据@user2864740
BigDecimal(1.0).divide(BigDecimal(2.0))
// returns 0.5
和
BigDecimal("1.0") / BigDecimal(2.0)
// returns 0.5
因此结果令人困惑。对于 BigDecimals,为什么 1.0 / 2.0
returns 0.0、1.0.divide(2.0)
returns 0.5 和 "1.0" / 2.0
returns 0.5?
1.1
是 double
文字
A floating-point literal is of type float if it ends with the letter F or f; otherwise its type is double and it can optionally end with the letter D or d.
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
因此,当值传递给 BigDecimal
时,您已经因为 double
值而失去了精度。 BigDecimal(1.1)
等同于 double d = 1.1; BigDecimal(d)
。您需要将值作为字符串
传递
BigDecimal("1.1")
除非该值可以精确表示为像 1.5
这样的双精度值
如果您明确地写 divide
,它的工作方式将与 Java 中的工作方式相同:
val a = BigDecimal(1.0)
val b = BigDecimal(2.0)
val x = a.divide(b) // 0.5
当您使用 /
运算符时,它转换为标准库中的 BigDecimal.div
扩展,它执行以下操作:
Enables the use of the / operator for BigDecimal instances.
The scale of the result is the same as the scale of this (divident), and for rounding the RoundingMode.HALF_EVEN rounding mode is used.
您可以看看不同的 RoundingMode
常量是如何工作的 here。
在 Kotlin 中,BigDecimal 除法 returns 奇怪的结果。
BigDecimal(1.0) / BigDecimal(2.0)
// returns 0.0
// Just like Int(1) / Int(2) returns 0
但是:
BigDecimal(1.1) / BigDecimal(2.0)
// returns 0.55
// Just like Double(1.1) / Double(2.0) returns 0.55
那么为什么会发生这种情况,我如何在不使用 divide()
给出比例参数的情况下使用 BigDecimal 使 1.0 / 2.0
returns 0.5?
更新:
完整代码如下:
Welcome to Kotlin version 1.2.41 (JRE 1.8.0_172-b11)
Type :help for help, :quit for quit
>>> import java.math.BigDecimal
>>> BigDecimal(1.0) / BigDecimal(2.0)
0
>>> BigDecimal(1.1) / BigDecimal(2.0)
0.550000000000000044408920985006261616945266723632812
更新 2:
根据@user2864740
BigDecimal(1.0).divide(BigDecimal(2.0))
// returns 0.5
和
BigDecimal("1.0") / BigDecimal(2.0)
// returns 0.5
因此结果令人困惑。对于 BigDecimals,为什么 1.0 / 2.0
returns 0.0、1.0.divide(2.0)
returns 0.5 和 "1.0" / 2.0
returns 0.5?
1.1
是 double
文字
A floating-point literal is of type float if it ends with the letter F or f; otherwise its type is double and it can optionally end with the letter D or d.
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
因此,当值传递给 BigDecimal
时,您已经因为 double
值而失去了精度。 BigDecimal(1.1)
等同于 double d = 1.1; BigDecimal(d)
。您需要将值作为字符串
BigDecimal("1.1")
除非该值可以精确表示为像 1.5
如果您明确地写 divide
,它的工作方式将与 Java 中的工作方式相同:
val a = BigDecimal(1.0)
val b = BigDecimal(2.0)
val x = a.divide(b) // 0.5
当您使用 /
运算符时,它转换为标准库中的 BigDecimal.div
扩展,它执行以下操作:
Enables the use of the / operator for BigDecimal instances.
The scale of the result is the same as the scale of this (divident), and for rounding the RoundingMode.HALF_EVEN rounding mode is used.
您可以看看不同的 RoundingMode
常量是如何工作的 here。