I have two different apps operating on two different Macs: a client and a server. They use HTTP to communicate. The server has an HTTP server which publishes plist files which encapsulates the data sent.
e.g.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>sensorName</key>
<string>external</string>
<key>temperature</key>
<real>8.8</real>
</dict>
</plist>
The Client uses an HTTPRequest and collects the data like so:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
DDLogVerbose(@"URL Connection succeeded! Received %ld bytes of data",[testReceivedData length]);
NSString *errorDescription = nil;
NSPropertyListFormat format;
NSDictionary *incomingPlist = [NSPropertyListSerialization propertyListFromData:testReceivedData
mutabilityOption:NSPropertyListImmutable
format:&format
errorDescription:&errorDescription];
if (errorDescription)
{
DDLogError(@"Error converting data from web into plist: %@", errorDescription);
return;
}
DDLogVerbose(@"We got a plist from the server: %@", incomingPlist);
NSString *sensorName;
switch ([self currentCommandType]) {
case MFRemoteCommandTypeSensorIndex:
[self setSensorNames:[incomingPlist objectForKey:@"sensorNames"]];
break;
case MFRemoteCommandTypeTemperature:
sensorName = [incomingPlist objectForKey:@"sensorName"];
if (!sensorName)
{
DDLogError(@"Could not get sensorname from temperature plist: %@", incomingPlist);
break;
}
[self didReceiveTemperatureReading:(NSNumber *)[incomingPlist objectForKey:@"temperature"] ForSensorName:sensorName];
break;
default:
DDLogError(@"We should never get here.");
break;
}
[self clearCurrentRequest];
}
So far so good…. and data is flowing between the two apps well and all is good in the world.
However, occasionally, and I cannot work out what the cause is, the client will interpret the temperature value incorrectly. i.e. instead of (as in the plist above) interpreting the temperature NSNumber as 8.8 it will interpret it as 8.800000000000001 or 9.2 as 9.199999999999999
Does anyone know why it would be doing this? The odd thing is that there doesn’t appear to be any pattern to when it does it…
Thanks in advance for any help.
Decimal numbers often don’t have exact representations in floating point formats, so if you’re reading the numbers as floats, you’re very likely to see them displayed as something very close but not exactly the same as what you expect. If you need an exact representation, take a look at NSDecimalNumber.
By the way, you should know that decimal numbers aren’t any more precise than binary representations except for those numbers which happen to have an exact decimal representation. For example, neither binary nor decimal representations can exactly represent 1/3.