代码很简单,您可以重现它。
NSDecimalNumber *d1 = [NSDecimalNumber decimalNumberWithString:@"6560601600245628933"];
BOOL res = [d1 isEqualToNumber:@(6560601600245628934)];
NSLog(@"%@", @(res));
isEqualToNumber:
始终返回YES
,即使我将d1
与@6560601600245628930
等其他数字进行比较......任何想法?这是一个错误吗?
答案 0 :(得分:2)
<强>分析强>
NSDecimalNumber
&#39; s compare:
(由isEqualToNumber:
调用)检查其参数(@(6560601600245628934)
此处)是另一个NSDecimalNumber
,如果不是NSNumber
的{{1}} compare:
是NSNumber
的超级班级。
当NSDecimalNumber
NSNumber
将其类型报告为d1
时,double
会返回CFNumberGetType()
- 并且kCFNumberDoubleType
{{1 {}} double
将这两个值比较为NSNumber
。
您的第一个值(compare:
)以double
的形式存储而没有重大损失,但其有效位数高于decimalNumberWithString:@"6560601600245628933"
且转换失去精确度。
您的第二个值(NSDecimalNumber
)由double
存储为64位整数(@(6560601600245628934)
)而没有精度损失,但转换为双精度丢失时。
根据这些变化,您在NSNumber
表示的时候尝试过这两个数字是相同的。
解决方法强>
变化:
kCFNumberSInt64Type
为:
double
直接从整数创建@(6560601600245628934)
值。这将导致[NSDecimalNumber numberWithLongLong:6560601600245628934LL]
的两个参数都为NSDecimalNumber
,并且在进行比较时不会丢失任何精度。
错误或功能?
它可能被归类为文档错误,因为我没有发现它在任何地方都有记录(这远非结论性!),将与isEqualToNumber:
进行比较秒。在bugreport.apple.com提交错误报告,看看他们说了什么。