gpt4 book ai didi

objective-c - NSJSONSerialization 是否将数字反序列化为 NSDecimalNumber?

转载 作者:太空狗 更新时间:2023-10-30 03:24:07 24 4
gpt4 key购买 nike

拿下面这段代码:

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 反序列化不会因为 double / float 等而导致舍入。

例如如果它被解释为 float ,我会精确地遇到这样的问题:

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

但后来我发现调用 NSDecimalNumber 上的 stringValue 无论如何都不会打印所有有效数字,例如...

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 数字,所以我知道这是否真的有必要。

最佳答案

NSJSONSerialization(和 Swift 中的 JSONSerialization)遵循一般模式:

  1. 如果数字只有整数部分(没有小数或指数),尝试将其解析为long long。如果没有溢出,返回一个 NSNumberlong long
  2. 尝试使用 strtod_l 解析 double 。如果它没有溢出,返回一个 NSNumberdouble
  3. 在所有其他情况下,尝试使用 NSDecimalNumber,它支持更大范围的值,特别是最多 38 位的尾数和 -128...127 之间的指数。

如果您查看人们发布的其他示例,您会发现当值超出 double 的范围或精度时,您会返回一个 NSDecimalNumber

关于objective-c - NSJSONSerialization 是否将数字反序列化为 NSDecimalNumber?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17986409/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com