Skip to content
Advertisement

How to make BigDecimal division more precise

I’m having an issue with BigDecimals, the simplified idea is to:

  • define a value for the total
  • split the total in 3 parts defined by weights, these weights are 3 double values that add up to 100.0
  • sum up the parts
  • the sum should be close to the total, the error should be at most 0.00000001

Here’s the failing test:

    @Test
    fun sanityCheckExampleForStackOverflow() {
        val whole = BigDecimal.valueOf(2_000_000_000.00)
        val weights = listOf("25.453778250984232", "35.38647064849812", "39.15975110051765").map { BigDecimal(it) }

        val parts = weights.map { weight ->
            // w / 100 * total
            weight.divide(BigDecimal(100)).times(whole)
        }

        val sumOfParts = parts[0] + parts[1] + parts[2]
        val difference = sumOfParts - whole

        assertTrue(difference <= BigDecimal("0.00000001"))
    }

What’s missing?

Advertisement

Answer

Given your weights sum to 100.000000000000002, the value of sumOfParts is 2000000000.000000040, which is 0.00000004 from your original value, which is four times bigger than the desired difference of 0.00000001.

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement