Search code examples
javakotlinbigdecimalinteger-overflowdecimalformat

Getting incorrect results from DecimalFormat.format() for large numbers


val numberFormatter = NumberFormat.getNumberInstance(Locale.getDefault())
val conversionPattern = "#,##0.####"
val decimalFormatter = numberFormatter as DecimalFormat
decimalFormatter.applyPattern(conversionPattern)

decimalFormatter.format("9999999999999999".toDouble()) // Getting -> "10,000,000,000,000,000"
                                                       // Need    ->  "9,999,999,999,999,999"

What's going wrong? Is it overflow? I am dealing with really large numbers so I'm using BigDecimal for the underlying value but to format it with grouping separators there's no format() function that accepts BigDecimal. How can I format numbers with at least 20 digits?


Solution

  • Use BigDecimal or BigInteger for numbers as large as this. For example:

    decimalFormatter.format(new BigDecimal("9999999999999999"))
    

    A double precision floating point number has only around 15-16 decimal digits of precision. Your number has 16 nines. There is no double precision floating point number exactly equal to 9999999999999999, so it is rounded to the closest one - which happens to be 1016.