如何确定Cocoa中的NSNumber
是否表示NaN(非数字)?
例如,当我解析一个包含无效(非数值)内容的字符串时会出现这种情况。
如何确定Cocoa中的NSNumber
是否表示NaN(非数字)?
例如,当我解析一个包含无效(非数值)内容的字符串时会出现这种情况。
所以,我发现类属性 [NSDecimalNumber notANumber]
就是为了这个目的。在某些语言中,NaN!= NaN,但在Cocoa中不是这种情况。
如Mike Abdullah所说,Cocoa中表示NaN的自然方式是使用nil
,但[NSNumber numberWithDouble:NAN]
确实会返回一个有效的对象。没有NSNumber
特定的方法来检测这一点,但通用的方法isnan([foo doubleValue])
可以工作。如果您不喜欢函数,您可以把它放在一个类别中。
nil
是表示像OP例子中带有非数字常量的字符串的自然方式。 - Jens Ayton对于小数,至少:
[[NSDecimalNumber notANumber] isEqualToNumber:myNumber]
要确定NSNumber是否为NaN,请将其转换为double,并使用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"
isnormal(0)
返回 0(与 isnormal(NAN)
相同),所以如果零是一个可能有效的值,请同时检查 inan
和 isinf
。使用 isfinite()
更好。 - Demitri我发现这个方法可行,但是它是否合法?
NSNumber *NaN = [NSDecimalNumber notANumber];
NSDecimalNumber *x = ... fill it somehow with NaN content ...
if ( x == NaN ) ... this works
NaN
是否保证是一个singleton
常量值?这样会很酷,但我认为并不是这样,因为我找到的所有例子都使用了isEqual
方法。
还有一个函数isnan(),我今天发现了它。
if(isnan(myNumber))
{ // myNumber is NaN .
}
任何带有NaN的布尔表达式都将始终返回false。但这有什么用呢?
在处理iPhone应用程序中的某些手势时,我从locationInView:中得到了NaN。很高兴发现任何带有NaN的布尔表达式都将始终返回false。我像下面这样使用它:
//我正在使用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的情况下,比较将为false。我可以安全地避免使用NaN进行计算。
实际上,NSNumber 并没有这样的对象,因为如果它不是一个数字,那么它就不是 NSNumber。更常见的做法是使用 nil 对象来表示这个。
[NSNumber isEqualToNumber:[NSDecimalNumber notANumber]]
。如果NSNumber是NaN,则这将返回YES。 - SimonB