代码之家  ›  专栏  ›  技术社区  ›  Ibrahim Disouki

Kotlin Double或BigDecimal之和返回意外结果

  •  0
  • Ibrahim Disouki  · 技术社区  · 2 年前

    我试图得到双倍值的总数,但它返回了意外的结果。查看以下屏幕截图: enter image description here

    链接 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

    2 回复  |  直到 2 年前
        1
  •  2
  •   broot    2 年前

    在大多数情况下,最好向客户提供数字 BigDecimal 作为字符串,而不是浮动:

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

    它解决了你的问题。

    简单解释一下:浮点数本质上不精确,无法存储小数。它们只提供了一个接近的结果,但不是我们预期的结果。

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

        2
  •  1
  •   Karsten Gabriel    2 年前

    问题是你要实例化你的 BigDecimal 他在用什么 Double 导致舍入问题的值。

    你可以写:

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

    那么你的结果是 10.0 .