2

I receive the following JSON response:

{
  "id": 1,
  "value": 519.6365
}

But when I convert the value to Double, I get: 519.63649999999996

How to keep the original value? (without rounding it)

glennsl
  • 28,186
  • 12
  • 57
  • 75
Manu
  • 23
  • 2
  • 6
  • 3
    See [Is floating point math broken?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – Eric Aya Jan 23 '17 at 14:02
  • 1
    Possible duplicate of [Is floating point math broken?](http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – JAL Jan 23 '17 at 14:12
  • 1
    Note that printing an *optional* double uses a different precision than printing a non-optional double (compare http://stackoverflow.com/questions/39770303/swift-issue-in-converting-string-to-double). So unwrapping the (presumably) optional makes it at least *appear* as you expect (even if it does not change the precision issue). – Martin R Jan 23 '17 at 14:16

2 Answers2

1

In such case using Foundation's NSNumber would be better solution. Converts the json value to NSNumber and it can always be downcast to Double Value

In Swift 4 -

let json = [
    "id": 1,
    "value": 519.6365
]

let value = (json["value"]! as NSNumber).doubleValue
print(value)  // Outputs - 519.6365

In cases where server sends the value as string, it would need to be first casted as String then to double value as -

value = (json["value"]! as NSString).doubleValue
Bishal Ghimire
  • 2,580
  • 22
  • 37
  • Unfortunately you can't use `NSNumber` with a `Codable` struct (Swift 5) to encode the struct as JSON automatically, it'll just display an error: `Type 'MyCodableStruct' does not conform to protocol 'Decodable'`. – Neph May 28 '19 at 14:52
-1

Double is like long Float,

Double represents a 64-bit floating-point number.

Float represents a 32-bit floating-point number.

So when you cast to Double, 32 bits is added to the variable, causing the change you see.

To keep the number as it is, you need to cast the variable to Float meaning the smaller floating point number.

var value:Float = 519.6365
var valueDouble = Double(value) // 519.636474609375
Float(valueDouble) // 519.6365 
Action Item
  • 99
  • 1
  • 1
  • 1
    Both `value` and `valueDouble` hold the value `519.636474609375`, they are only *printed* with a different precision. And nowhere in the above problem is a Float cast to Double. – Martin R Jan 23 '17 at 16:24