采取以下代码:
NSError *error;
NSString *myJSONString = @"{ \"foo\" : 0.1}";
NSData *jsonData = [myJSONString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *results = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
我的问题是,是results[@"foo"]
NSDecimalNumber,还是具有有限二进制精度的东西,如 double 或 float?基本上,我有一个应用程序需要带有 的无损准确性NSDecimalNumber
,并且需要确保 JSON 反序列化不会因为双精度/浮点数等而导致舍入。
例如,如果它被解释为浮点数,我会精确地遇到这样的问题:
float baz = 0.1;
NSLog(@"baz: %.20f", baz);
// prints baz: 0.10000000149011611938
我尝试将其解释foo
为 NSDecimalNumber 并打印结果:
NSDecimalNumber *fooAsDecimal = results[@"foo"];
NSLog(@"fooAsDecimal: %@", [fooAsDecimal stringValue]);
// prints fooAsDecimal: 0.1
但后来我发现调用stringValue
anNSDecimalNumber
并不会打印所有有效数字,例如..
NSDecimalNumber *barDecimal = [NSDecimalNumber decimalNumberWithString:@"0.1000000000000000000000000000000000000000000011"];
NSLog(@"barDecimal: %@", barDecimal);
// prints barDecimal: 0.1
...所以打印fooAsDecimal
并不能告诉我results[@"foo"]
JSON 解析器是否在某个时候四舍五入到有限精度。
明确地说,我意识到我可以在 JSON 表示中使用字符串而不是数字来存储 foo 的值,即"0.1"
代替0.1
,然后使用[NSDecimalNumber decimalNumberWithString:results[@"foo"]
]。但是,我感兴趣的是 NSJSONSerialization 类如何反序列化 JSON 数字,所以我知道这是否真的有必要。