NSNumber比较:返回不同的结果

Mat*_* W. 7 iphone objective-c nsnumber

我正在尝试进行一些数字比较,我得到了一些奇怪的结果.

NSNumber* number1 = [NSNumber numberWithFloat:1.004];
NSNumber* number2 = [NSNumber numberWithDouble:1.004];

([number1 compare:number2] == NSOrderedSame) ? NSLog(@"YES") : NSLog(@"NO");
([number1 compare:number2] == NSOrderedAscending) ? NSLog(@"YES") : NSLog(@"NO");
([number1 doubleValue] == [number2 doubleValue]) ? NSLog(@"YES") : NSLog(@"NO");
([number1 floatValue] == [number2 floatValue]) ? NSLog(@"YES") : NSLog(@"NO");
Run Code Online (Sandbox Code Playgroud)

日志输出:

NO
YES
NO
YES

这对我来说非常令人沮丧.我知道这可能是因为浮点数与双精度数之间的差异.在我看来,它正在将双倍缩减到浮点数来进行比较.但如果我不知道如何创建数字,我该如何得到正确的结果呢?是否有不同的方法来比较NSNumber?

SSt*_*eve 7

我尝试使用isEqualToNumber:它返回NO.它们不相同的原因是因为1.004不能完全用二进制表示.该double近似有小数点比经过数字float逼近所以这两个数字是不同的.通常,在比较浮点数时,您要测试它们是否等于容差值fabs(a - b) < tolerance:

NSNumber* number1 = [NSNumber numberWithFloat:1.004];
NSNumber* number2 = [NSNumber numberWithDouble:1.004];

NSLog(@"number 1: %.12f", [number1 doubleValue]);
NSLog(@"number 2: %.12f", [number2 doubleValue]);

([number1 isEqualToNumber:number2]) ? NSLog(@"YES") : NSLog(@"NO");
fabs([number1 floatValue] - [number2 doubleValue]) < 1.0e-7 ? NSLog(@"YES") : NSLog(@"NO");
Run Code Online (Sandbox Code Playgroud)

结果:

2012-02-09 15:08:34.272 so9219935[3313:903] number 1: 1.003999948502
2012-02-09 15:08:34.274 so9219935[3313:903] number 2: 1.004000000000
2012-02-09 15:08:34.275 so9219935[3313:903] NO
2012-02-09 15:08:34.275 so9219935[3313:903] YES
Run Code Online (Sandbox Code Playgroud)

  • Apple(或者更确切地说,编译器编写者)不能对程序员对平等的容忍度做出假设.他们只能做的就是程序员告诉他们要做的事情.在这种情况下,您正在比较两个不相等的值.浮点数不是一个微不足道的主题.如果你有时间,看看[每个计算机科学家应该知道的关于浮点算术的内容](http://www-users.math.umd.edu/~jkolesar/mait613/floating_point_math.pdf). (5认同)