Double 或 BigDecimal return 意外结果的 Kotlin 总和

Kotlin sum of Double or BigDecimal return unexpected result

我正在尝试获取 double 值的总数,但它 returns 出乎意料的结果。检查以下屏幕截图:

Link 对于 the code 代码:

import java.math.BigDecimal
/**
 * You can edit, run, and share this code.
 * play.kotlinlang.org
 */
fun main() {
    val items = listOf(MyItem(BigDecimal(3.6)), MyItem(BigDecimal(2.0)), MyItem(BigDecimal(4.3)), MyItem(BigDecimal(0.1)))
    println(items.sumOf { it.amount })
}

data class MyItem(val amount: BigDecimal)

预期结果是:10.0

实际结果是:9.9999999999999999167332731531132594682276248931884765625

问题是您使用 Double 值实例化 BigDecimal,这会导致舍入问题。

您可以改写:

val items = listOf(MyItem(BigDecimal("3.6")), MyItem(BigDecimal("2.0")), MyItem(BigDecimal("4.3")), MyItem(BigDecimal("0.1")))

那么你的结果是10.0

在大多数情况下,最好将数字作为字符串而不是浮点数提供给 BigDecimal

val items = listOf(MyItem(BigDecimal("3.6")), MyItem(BigDecimal("2.0")), MyItem(BigDecimal("4.3")), MyItem(BigDecimal("0.1")))

它解决了你的问题。

几句话的解释:floating-point 数字在存储小数方面本质上是不精确的。它们只提供了接近的结果,而不是我们所期望的结果。

BigDecimal 试图解决这个问题。它使用一些技巧来表示我们所期望的数字。但要做到这一点,它需要了解我们要如何表示数字,我们期望的精度是多少等等。它可以从字符串提供的数字中扣除,但不能从 floats/doubles.

中扣除