如何确定 Cocoa 是否NSNumber
代表 NaN(不是数字)?
例如,当我解析具有无效(非数字)内容的字符串时,就会出现这种情况。
如何确定 Cocoa 是否NSNumber
代表 NaN(不是数字)?
例如,当我解析具有无效(非数字)内容的字符串时,就会出现这种情况。
所以,我发现类属性[NSDecimalNumber notANumber]
就是为了这个目的。在某些语言中 NaN != NaN,但在 Cocoa 中并非如此。
正如 Mike Abdullah 所说,在 Cocoa 中表示 NaN 的自然方式是使用nil
,但[NSNumber numberWithDouble:NAN]
确实返回一个有效对象。没有NSNumber
特定的方法可以检测到这一点,但一般方法isnan([foo doubleValue])
, 有效。如果你不喜欢函数,你可以把它放在一个类别中。
对于小数,至少:
[[NSDecimalNumber notANumber] isEqualToNumber:myNumber]
要确定 NSNumber 是否为 NaN,请将其转换为双精度并使用 C 函数isnan()
:
NSNumber *validNumber = [NSNumber numberWithDouble: 1.];
NSLog( @"%d", isnan(validNumber.doubleValue) ); // prints "0"
NSNumber *nanNumber = [NSNumber numberWithDouble: 0./0.];
NSLog( @"%d", isnan(nanNumber.doubleValue) ); // prints "1"
但是,您应该小心,因为还有其他特殊值,例如:
NSNumber *posInfinity = [NSNumber numberWithDouble: 1./0.];
NSLog( @"%d", isnan(posInfinity.doubleValue) ); // prints "0"
如果您还想检查这些值,最好isnormal()
改用:
NSLog( @"%d", isnormal(validNumber.doubleValue) ); // prints "1"
NSLog( @"%d", isnormal(nanNumber.doubleValue) ); // prints "0"
NSLog( @"%d", isnormal(posInfinity.doubleValue) ); // prints "0"
我发现这行得通,但它合法吗?
NSNumber *NaN = [NSDecimalNumber notANumber];
NSDecimalNumber *x = ... fill it somehow with NaN content ...
if ( x == NaN ) ... this works
NaN
保证是一个常singleton
数值?会很酷,但我想不是,因为我发现的所有示例都使用这些isEqual
方法。
还有我今天发现的函数 isnan()。
我们也可以使用在 math.h 中定义的#define 如下
if(isnan(myNumber))
{ // myNumber is NaN .
}
任何带有 NaN 的布尔表达式将始终返回 false。但这有什么用呢?
我在处理 iPhone 应用程序中的一些手势时,正在从 locationInView 中让 Nan 回来。并且非常高兴地发现任何带有 NaN 的布尔表达式将始终返回 false。我把它用在下面的liek:
//我正在使用UIPanGestureRecognizer
, 并且似乎在 TouchUp 上我会为 /location .x - .y - 获得 Nan 非常合理,因为在这种情况下,触摸结束没有位置。
CGPoint location = [gestureRecognizer locationInView:self];
if ( location.x != location.x || location.y != location.y )
{
return;
}
那么只要 .x 和 .y 或合法的浮点值,当然它们永远不会不等于它们自己的值。但是在 .x 或 .y 为 NaN 的情况下,比较将是错误的。而且我可以安全地避免使用 Nan 进行计算。
NSNumber 并没有这样的对象,因为如果它不是一个数字,那么,好吧,它不是一个 NSNumber。使用 nil 对象来表示这一点更为常见。