Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSONObjectWithData wrong decimal places while parsing

In one of my api I am getting below response form server (If convert data into string)

{"success":true,"order_id":102232,"Total":68.6,"delivery_time":"7:30PM-10:00PM","delivery_date":"2016-03-25"}

But when I used the same with

[NSJSONSerialization JSONObjectWithData:data options:self.readingOptions error:&serializationError];

Its return

{
Total = "68.59999999999999";
"delivery_date" = "2016-03-25";
"delivery_time" = "7:30PM-10:00PM";
"order_id" = 102232;
success = 1;

}

Due to multiple places after decimal in total field its creating problem in calculation.

I think the JSON serialization method converting it internally but don't know how to resolve this

like image 758
Tarun Seera Avatar asked Apr 17 '26 12:04

Tarun Seera


2 Answers

@gnasher hinted at the issue, but didn't explain it in detail.

Computers use binary floating point to represent floating point numbers internally.

A floating point number is usually stored as either a float or a double. On most 64 bit platforms a float is stored in 4 bytes and a double is stored in 8 bytes.

Binary floating point can't represent many decimal values exactly. Internally, 68.6 is represented in binary as a value that works out to 68.59999999999999 in decimal. That is the closest that a computer can get to 68.6 when saving your value as a float.

Binary floating point values like floats and doubles do not have a "number of decimal places." The value gets converted to decimal for display, or for conversion to a string, and there is always the potential for rounding errors in that conversion.

Take this code for example:

float aFloat = 68.6;
NSLog(@"aFloat = %f", aFloat);

That displays:

aFloat = 68.599998

However, this code:

NSLog(@"aFloat (1 decimal place)= %.1f", aFloat);

Displays:

aFloat (1 decimal place)= 68.6

The JSON string you are parsing has numbers in it that are not in quotes. When you convert your JSON string to a Cocoa object, the value of "Total" gets saved as an NSNumber object, probably using a double type internally.

If you need to do math on your "Total" value then you need it to be a number.

If you want to avoid decimal conversion errors, change your server code to send the value "Total" as a string, (in quotes) not a numeric value. Then the JSONObjectWithData function will keep it as a string, "68.6"

In that case your JSON string would look like this:

{"success":true,"order_id":102232,"Total":"68.6","delivery_time":"7:30PM-10:00PM","delivery_date":"2016-03-25"}

You said "Due to multiple places after decimal in total field its creating problem in calculation." What problem? On the iOS side, or the server side?

like image 122
Duncan C Avatar answered Apr 19 '26 02:04

Duncan C


This resolved my problem

NSNumberFormatter *fmt = [[NSNumberFormatter alloc] init];
[fmt setPositiveFormat:@"0.##"];
NSLog(@"%@", [fmt stringFromNumber:dataDict[@"Total"]]);

Output of this log is 68.6

like image 28
Tarun Seera Avatar answered Apr 19 '26 02:04

Tarun Seera