NSDecimalNumber和大型无符号长整数(64位)整数

14

我正在处理从JSON源获取的大型64位无符号整数,这些数字被解析为NSDecimalNumbers,它显然是为了“忠实地表示任意精度的数字”而设计的。

我的问题是,我无法从这个类中获取正确的数字。例如(使用最大可能值):

print (unsigned long long) [[NSDecimalNumber decimalNumberWithString:@"18446744073709551615"] unsignedLongLongValue]
= 0 // Incorrect
print (unsigned long long) [[NSDecimalNumber decimalNumberWithString:@"9223372036854775808"] unsignedLongLongValue]
= 9223372036854775808 // Correct
print (unsigned long long) [[NSDecimalNumber decimalNumberWithString:@"9223372036854775810"] unsignedLongLongValue]
= 9223372036854775808 // Incorrect

看起来我无法从NSDecimalNumber中获取大于最大有符号long long值的任何值。 它不喜欢大于9223372036854775808的值。 但是,似乎该数字在NSDecimalNumber中以完整精度存储,如下所示:

po [[NSDecimalNumber decimalNumberWithString:@"18446744073709551615"] stringValue]
= 18446744073709551615

我注意到 NSNumber 对象可以正确处理这些大数,并且 unsignedLongLongValue 可以正常工作。只有 NSDecimalNumbers(我被迫使用)不起作用。

我该如何从 NSDecimalNumbers 中获取正确的无符号长整型值?或者至少将它们转换为 NSNumber 对象,其中 unsignedLongLongValue 可以正常工作。

2个回答

11

我在开发者论坛上收到了苹果公司的回复:

这是NSDecimalNumber的一个常见问题,简单访问器(如[unsigned]longLongValue)会通过doubleValue访问器 - 因此,任何需要超过53位精度的值将被不适当地舍入。请随意报告此问题并提及错误编号8220543。

话虽如此,如果你只是从JSON中获取64位数字,你应该可以直接使用NSNumber,而不是NSDecimalNumber。

因此,我通过将解析器从SBJson更改为JSONKit来解决此问题,这不仅速度更快,还将数字映射到NSNumber对象而不是NSDecimalNumber对象中。


1
我想知道在iOS 5的NSJSONSerialization类中是否仍存在这个问题? - adib
它在iOS 5的NSJSONSerialization中完全持久存在!o_O - Hans Sjunnesson
苹果似乎仍未在OSX 10.9.2中修复此漏洞 :( - snakeninny

6
如果您仍希望从NSDecimalNumber中提取无符号长整型值,可以使用johne在此处提出的方法,并执行以下操作:
NSDecimalNumber *testNumber = [NSDecimalNumber decimalNumberWithString:@"18446744073709551615"];
unsigned long long ullvalue = strtoull([[testNumber stringValue] UTF8String], NULL, 0);
NSLog(@"Number:%llu", ullvalue);

我尝试使用NSScanner来实现这个:

数字:18446744073709551615

它会产生正确的结果。

NSScanner *theScanner = [[NSScanner alloc] initWithString:[testNumber stringValue]];
unsigned long long outputValue;

[theScanner scanLongLong:(long long *)&outputValue];
[theScanner release];

不幸的是,它只能读取带符号的长长整型值,因此上述代码给出了错误的值9223372036854775807。


谢谢您的建议,如果您被NSDecimalNumbers困住了,这是一个好主意! - Michael Waterfall

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接