I was testing some simple solution for my app, and I ran into some case where question comes up in my head... "Why one floating number is represented in JSON correctly (as I expect) and other one not...?"
in this case conversion from String to Decimal and then to JSON of number: "98.39" is perfectly predictable from human point of view, but number: "98.40" doesn't look so beautiful...
And my question is, could someone explain please to me, why conversion from String to Decimal works as I expect for one floating number, but for another it is not.
I have red a lot about Floating Point number error, but I can't figure it out how the proces from String ->... binary based conversion stuff...-> to Double has different precision for both cases.
My playground code:
struct Price: Encodable {
let amount: Decimal
}
func printJSON(from string: String) {
let decimal = Decimal(string: string)!
let price = Price(amount: decimal)
//Encode Person Struct as Data
let encodedData = try? JSONEncoder().encode(price)
//Create JSON
var json: Any?
if let data = encodedData {
json = try? JSONSerialization.jsonObject(with: data, options: [])
}
//Print JSON Object
if let json = json {
print("Person JSON:\n" + String(describing: json) + "\n")
}
}
let stringPriceOK = "98.39"
let stringPriceNotOK = "98.40"
let stringPriceNotOK2 = "98.99"
printJSON(from: stringPriceOK)
printJSON(from: stringPriceNotOK)
printJSON(from: stringPriceNotOK2)
/*
------------------------------------------------
// OUTPUT:
Person JSON:
{
amount = "98.39";
}
Person JSON:
{
amount = "98.40000000000001";
}
Person JSON:
{
amount = "98.98999999999999";
}
------------------------------------------------
*/
I was looking/trying to figure it out what steps has been performed by the logical unit to convert: "98.39" -> Decimal -> String - with result of "98.39" and with the same chain of conversion: "98.40" -> Decimal -> String - with result of "98.40000000000001"
Many thanks for all responses!