I am trying to convert a class object to JSON string to display on screen but Double
datatypes are getting wrong values.
Here is my code
struct Wallet: Codable {
var balance: Double
var limit: Double
var currency: String
}
func showJSON() {
let data = Wallet(balance: Double(200.24), limit: Double(5000), currency: "INR")
let result = convertToJSONString(data)
print(result!)
}
func convertToJSONString<T: Codable>(_ response: T) -> String? {
var jsonString: String?
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
if let data = try? jsonEncoder.encode(response) {
jsonString = String(data: data, encoding: .utf8)
}
return jsonString
}
//function call
showJSON()
And my output is
{
"balance" : 200.24000000000001,
"limit" : 5000,
"currency" : "INR"
}
Check the balance value here, we have provided 200.24 but after conversion it showing as 200.24000000000001. Can someone suggest what needs to be change here to have exact output?
Note* - You can copy paste this code to playground directly, it will work without any modifications.
As @Devid commented above, floating points are not always accurate and conversion from Double
or Float
to String
get impacted.
So, instate of doing conversion to String
we can always hold JSON in Any
datatype to print/show.
Basically, it won't do conversion so values wont get impacted.
Here, I Just replaced the convertToJSONString
function in above implementation like
func convertToJSONString<T: Codable>(_ response: T) -> Any? {
var jsonString: Any?
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
if let data = try? jsonEncoder.encode(response) {
jsonString = try? JSONSerialization.jsonObject(with: data, options: [])
}
return jsonString
}
used JSONSerialization
and getting output as
{
balance = "200.24";
currency = INR;
limit = 5000;
}
It is useful to show big and complex JSON with original Double
or Float
values and to make use of it you can always hold them in relevant datatypes so values wont get impacted.