2011-07-15 39 views
14

我正在处理来自JSON源的大型64位无符号整数,这些JSON源被解析为NSDecimalNumbers,这显然是“忠实地表示任意精度数字”。NSDecimalNumber和大的无符号long long(64位)整数

我遇到的问题是我不能从这个类中得到正确的数字。例如(使用最大可能值):

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 

这样看来,我不能得到任何比符号long long值出NSDecimalNumber的最大大。但是似乎号被存储在一个NSDecimalNumber内全精度它不喜欢比9223372036854775808.较大的值,如:

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

我注意到,NSNumber的对象可以处理这些大量的罚款和unsignedLongLongValue作品正确。这只是NSDecimalNumbers(我坚持)哪些不起作用。

如何从NSDecimalNumbers中得到正确的无符号long long值?或者至少将它们转换为unsignedLongLongValue工作的NSNumber对象。

回答

11

我已经从苹果公司在这个问题上通过开发者论坛的回应:

这是一个存在的问题与NSDecimalNumber在简单 存取(如[无符号] longLongValue)经过的doubleValue 存取器 - 这个任何值需要超过53位的精度 将被不适当地四舍五入。随意举报这个 问题的Bug和提bug数8220543.

也就是说,如果你是从JSON只是 得到的64位数字,你应该能够只使用 NSNumber的,而不是NSDecimalNumber。

所以我从SBJson改变解析器JSONKit,这不仅是更快的解决它,它也映射到数字对象的NSNumber,而不是NSDecimalNumber对象。

+1

我不知道问题是否在iOS 5中的NSJSONSerialization类仍然存在不正确的值? – adib

+0

我没有意识到这一点在iOS 5中,我会检查出来 - 谢谢! –

+0

它完全坚持在iOS 5的NSJSONSerialization! o_O –

6

如果你仍然想提取从NSDecimalNumber一个unsigned long long值,你可以使用由强尼here建议的方法,并做类似如下:

NSDecimalNumber *testNumber = [NSDecimalNumber decimalNumberWithString:@"18446744073709551615"]; 
unsigned long long ullvalue = strtoull([[testNumber stringValue] UTF8String], NULL, 0); 
NSLog(@"Number:%llu", ullvalue); 

产生的

正确的结果

编号:18446744073709551615

我尝试使用NSScanner做到这一点:

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

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

但不幸的是,它只能读取符号long long值,所以上面给出了9223372036854775807

+0

感谢您的建议,如果你困在NSDecimalNumbers! –