0

I have a server returning a value (in JSON) which contains a number with decimal places, e.g. 203.14.

Since in my app I need to do some calculation, I have to convert it to Double.

However when it is converted to Double, it's value becomes 203.13999938964844.

For some business logic reason, when I display this value, I need to round down this number to 2 decimal places.

So now it becomes 203.13, which is 0.01 smaller than the value server returns.

How can I preserve 203.14 when I convert "203.14" to Double?

Update:

I just found that the reason is because the model class used float to accept the server value, but then later converted to Double. If day one the model class uses double to accept the value, then the problem above will not exist.

Sira Lam
  • 4,412
  • 24
  • 53
  • Why doues rounding that value yield a smaller number? The given double value will only be rounded to `203.13` if you round down instead of arithmetic – Nico Haase Jun 02 '20 at 06:27
  • 3
    Does this answer your question? [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Robby Cornelissen Jun 02 '20 at 06:27
  • 2
    If you want precise floating point calculations, use a `BigDecimal`. If you just want to fix the display problem, round instead of truncating. – Robby Cornelissen Jun 02 '20 at 06:29
  • @NicoHaase Yes I have to round it down. – Sira Lam Jun 02 '20 at 06:32
  • 1
    Regarding your update: changing from float to double might fix the issue for this specific value, but it won't for all numbers. Doubles give you double the precision, but not absolute precision. – Robby Cornelissen Jun 02 '20 at 07:30

2 Answers2

0

Try using this rounding method after initializing the Double:

fun Double.round(decimals: Int): Double {
    var multiplier = 1.0
    repeat(decimals) { multiplier *= 10 }
    return round(this * multiplier) / multiplier
}

You can use it like this:

3.14159265359.round(2)
Programmer
  • 43
  • 1
  • 1
  • 8
-1

It appears to me that the number's real value is 203.1399999999999, but when you are outputting the data, the String format is rounding it to 203.14. If this is the case, then try to round the number before converting it to a Double.

If that doesn't work, try using either of the following methods instead of the one that you are currently using: Double.parseDouble() Double.valueOf()

Programmer
  • 43
  • 1
  • 1
  • 8
  • No, the value server returns is `203.14` exactly. – Sira Lam Jun 02 '20 at 06:31
  • What method are you using to convert 203.14 to a double? – Programmer Jun 02 '20 at 06:35
  • 1
    @SiraLam there's no way to represent 203.14 exactly in binary floating-point – phuclv Jun 02 '20 at 06:37
  • 1
    @SiraLam `value server returns is 203.14 exactly` No, because `203.14` does not have an exact (terminating) representation in the [IEEE-754](https://en.wikipedia.org/wiki/Double-precision_floating-point_format) floating point format that `double` uses. – dxiv Jun 02 '20 at 06:42