cocoa - Determine si NSNumber es NaN
(9)
Como dice Mike Abdullah, la forma natural de representar un NaN en Cocoa es nil
, pero [NSNumber numberWithDouble:NAN]
devuelve un objeto válido. No existe una NSNumber
específica de NSNumber
de detectar esto, pero la forma general, isnan([foo doubleValue])
, funciona. Si no le gustan las funciones, puede pegarlas en una categoría.
¿Cómo puedo determinar si un NSNumber de Cocoa representa NaN (no un número)?
Esto surge, por ejemplo, cuando analizo una cadena que tiene un contenido no válido (no numérico).
Cualquier expresión booleana con NaN siempre devolverá falsa. Pero, ¿cómo es eso útil?
Estaba recuperando a Nan de locationInView: mientras manejaba algunos gestos en una aplicación de iPhone. Y me complació mucho descubrir que cualquier expresión booleana con NaN siempre devolverá falsa. Puse esto para usar el nombre a continuación:
// Estaba usando el UIPanGestureRecognizer
, y parece que en TouchUp obtendría Nan para / location .x - .y - bastante razonable ya que en este caso el final de un toque no tiene una ubicación.
CGPoint location = [gestureRecognizer locationInView:self];
if ( location.x != location.x || location.y != location.y )
{
return;
}
Por lo tanto, siempre que los valores de .x y .y flotación sean legítimos, por supuesto, nunca serán iguales a su propio valor. PERO en el caso de que .x o .y sean NaN, la comparación será falsa. Y puedo evitar con seguridad los cálculos con Nan.
Descubrí que esto funciona, pero ¿es legal?
NSNumber *NaN = [NSDecimalNumber notANumber];
NSDecimalNumber *x = ... fill it somehow with NaN content ...
if ( x == NaN ) ... this works
¿ NaN
está garantizado como un valor constante singleton
? Sería genial, pero supongo que no, ya que todos los ejemplos que encontré usan los métodos isEqual
.
Para decimales, al menos:
[[NSDecimalNumber notANumber] isEqualToNumber:myNumber]
Para determinar si NSNumber es un NaN, conviértalo a un doble y use la función 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"
Sin embargo, debe tener cuidado, porque hay otros valores especiales, por ejemplo:
NSNumber *posInfinity = [NSNumber numberWithDouble: 1./0.];
NSLog( @"%d", isnan(posInfinity.doubleValue) ); // prints "0"
Si desea verificar también estos valores, es mejor usar isnormal()
lugar:
NSLog( @"%d", isnormal(validNumber.doubleValue) ); // prints "1"
NSLog( @"%d", isnormal(nanNumber.doubleValue) ); // prints "0"
NSLog( @"%d", isnormal(posInfinity.doubleValue) ); // prints "0"
Realmente no existe tal objeto para NSNumber ya que si no es un número, entonces, bueno, no es un NSNumber. Es más habitual utilizar un objeto nil para representar esto.
También podemos usar un #define definido en math.h como follws
if(isnan(myNumber))
{ // myNumber is NaN .
}
también está la función isnan () la encontré hoy.
Entonces, descubrí que la propiedad de la clase [NSDecimalNumber notANumber]
es solo para este propósito. En algunos idiomas NaN! = NaN, pero este no es el caso en Cocoa.