How we convert BigDecimal into Double without losing precision in Kotlin?. I need to put it in a JSON response.
I'm using Vert.x and JsonObject. I've tried converting BigDecimal with scale 2 to Double with toDouble
. Internally it uses Jackson as Object mapper
Example:
Currently:
BigDecimal("0.000")
-> Response: { amount: 0.0 }
What I need:
BigDecimal("0.000")
-> Response: { amount: 0.000 }
I'm afraid you can't convert a BigDecimal into a Double without losing precision, for several reasons:
Doubles are 64-bit, so can't have more than 2⁶⁴ distinct values, while BigDecimals are effectively unlimited.
Both can store integers exactly (up to a certain value), and both can store fractions such as 0.5 exactly. But nearly all decimal fractions can't be represented exactly as a binary fraction, and so for example there's no Double holding exactly 0.1. (1/10 is an infinite recurring fraction in binary — 0.0001100110011… — and so no finite binary fraction can represent it exactly.)
This means that in Kotlin (and most other programming languages), a numeric literal such as 0.1 gets converted to the nearest double-precision number, which is around 0.100000000000000005551115…. In practice, this is usually hidden from you, because when you print out a Double, the formatting routine will round it off, and in many cases that gives back the original number. But not always, e.g.:
>>> println(0.1 + 0.1 + 0.1)
0.30000000000000004
(All of this is discussed in other questions, most notably here.)
For example, both 1.0 and 1.000000 are represented by exactly the same Double value:
>>> println(1.000000)
1.0
I don't know Vert.x, but I'd be surprised if you really needed a Double here. Have you tried using a BigDecimal directly?
Or if that doesn't work, have you tried converting it to a String, which will preserve whatever formatting you want?