Как определить, существует ли Cocoa NSNumber NaN (не число)?
Это возникает, например, при анализе строки с недопустимым (нечисловым) содержимым.
Как определить, существует ли Cocoa NSNumber NaN (не число)?
Это возникает, например, при анализе строки с недопустимым (нечисловым) содержимым.
Итак, я узнал, что свойство класса [NSDecimalNumber notANumber]
подходит именно для этой цели. В некоторых языках NaN!= NaN, но это не так в Cocoa.
Как говорит Майк Абдулла, естественным способом представления NaN в Cocoa является nil
, но [NSNumber numberWithDouble:NAN]
возвращает действительный объект. Существует не NSNumber
-специальный способ обнаружения этого, но общий способ, isnan([foo doubleValue])
, работает. Если вам не нравятся функции, вы можете вставить его в категорию.
Для десятичных знаков, по крайней мере:
[[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"
Я обнаружил, что это работает, но является ли оно законным?
NSNumber *NaN = [NSDecimalNumber notANumber];
NSDecimalNumber *x = ... fill it somehow with NaN content ...
if ( x == NaN ) ... this works
является NaN
гарантированным как постоянное значение singleton
? Было бы здорово, но я полагаю, что это не так, поскольку все примеры, которые я нашел, используют методы isEqual
.
существует также функция isnan(), которую я нашел сегодня.
Мы также можем использовать #define, определенный в math.h, как описано ниже
if(isnan(myNumber))
{ // myNumber is NaN .
}
Любое булево выражение с NaN всегда будет возвращать false. Но как это полезно?
Я возвращал Nan из locationInView: при обработке некоторых жестов в приложении для iPhone. И было очень приятно найти, что любое булево выражение с NaN всегда будет возвращать false. Я поставил это на использование liek ниже:
//Я использовал UIPanGestureRecognizer
, и кажется, что на TouchUp я бы получил Nan для /location.x -.y - довольно разумно, так как в этом случае конец touch не имеет местоположения.
CGPoint location = [gestureRecognizer locationInView:self];
if ( location.x != location.x || location.y != location.y )
{
return;
}
Итак, до тех пор, как долго .x и .y или законные значения float, конечно, они никогда не будут равны собственной стоимости. НО в случае .x или .y, являющихся NaN, сравнение будет ложным. И я могу безопасно избегать вычислений с Нан.
На самом деле нет такого объекта для NSNumber, поскольку, если это не число, то, ну, это не NSNumber. Это более обычное использование объекта nil для представления этого.