Search code examples
kotlinmathsumdoublebigdecimal

Kotlin sum of Double or BigDecimal return unexpected result


I'm trying to get the total amount of double values but it returns unexpected results. Check the following screenshot: enter image description here

Link for the code 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)

The expected result is: 10.0

The actual result is: 9.9999999999999999167332731531132594682276248931884765625


Solution

  • In most cases it is better to provide numbers to BigDecimal as strings, not floats:

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

    It solves your problem.

    Few words of explanation: floating-point numbers are by nature imprecise for storing decimal fractions. They only provide a close result, but not the one we would expect.

    BigDecimal tries to fix this problem. It makes some tricks to represent the number as we would expect. But to do this it needs to understand how do we want to represent numbers, what is our expected precision, etc. It can deduct this from numbers provided by strings, but not from floats/doubles.