0

The calculation below should result in "3.52" but outputs "3.5199999999999996". How can I fix this?

("4.52".toDouble() - 1).toString()
Raj Narayanan
  • 2,443
  • 4
  • 24
  • 43
  • 3
    See also https://stackoverflow.com/questions/588004/is-floating-point-math-broken – Tenfour04 Dec 16 '22 at 05:54
  • Isn't this question a duplicate of the (classic) one Tenfour04 linked? (And why does [this](/a/74245972/10134209) [keep](/a/56134099/10134209) [coming](/a/59947856/10134209) [up](/a/69080938/10134209)? Is there some misguided textbook or class somewhere claiming that floating-point _does_ store exact decimal values and _is_ suitable for amounts of money??) – gidds Dec 16 '22 at 14:38
  • @gidds, I would have closed as duplicate except they seem to be asking specifically about how to work around this in Kotlin. I remember having to learn this the hard way my first week self-teaching programming. It's easy as a beginner to miss [the little line](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html) that says "don't use this for currency" when looking at that wall of text, when you don't have a professor to shout, "DON'T USE THIS FOR CURRENCY!" – Tenfour04 Dec 16 '22 at 14:46

2 Answers2

1

You can also use roundToInt() method to achieve the result as follows

val random = 4.52 - 1
val roundoff = (random * 100.0).roundToInt() / 100.0
println(roundoff) //3.52
 
Suraj Bahadur
  • 3,730
  • 3
  • 27
  • 55
  • 1
    `4.52` is already Double or Float. so you don't need to cast via `toDouble()`. 'OR' you can use `"4.52"` as asked in question which is `String` – Mrugesh Tank Dec 16 '22 at 07:26
  • That may give the correct result in this particular case, but there are others where it won't. (E.g. if the value is close to 351.999999.) And you can't just fix that by changing the cut-off point; floating-point calculations accumulate round-off errors and there will always be corner cases. The only solution, if you need exact values, is not to use floating-point in the first place. Especially when Kotlin makes it so easy to use e.g. `BigDecimal` instead. – gidds Dec 16 '22 at 14:53
  • @gidds I actually ended up using `BigDecimal`. – Raj Narayanan Dec 16 '22 at 18:38
0

You can use String.format() function like

String.format(Locale.US,"%.2f","4.52".toDouble() - 1)

The .2f means this argument should be formatted as a float and with a precision of 2 digits after the Decimal.

Suraj Bahadur
  • 3,730
  • 3
  • 27
  • 55
Umang
  • 133
  • 1
  • 7