Determinar si NSNumber es NaN


¿Cómo puedo determinar si un NSNumber de Cacao representa NaN (no un número)?

Esto surge, por ejemplo, cuando analizo una cadena que tiene un contenido no válido (no numérico).

Author: Adam Ernst, 2009-04-05

9 answers

Entonces, descubrí que la propiedad de clase [NSDecimalNumber notANumber] es solo para este propósito. En algunos idiomas NaN != NaN, pero este no es el caso en Cocoa.

 63
Author: Adam Ernst,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-05 18:33:58

Como dice Mike Abdullah, la forma natural de representar una NaN en Cocoa es con nil, pero [NSNumber numberWithDouble:NAN] devuelve un objeto válido. No hay NSNumber una forma específica de detectar esto, pero la forma general, isnan([foo doubleValue]), funciona. Si no te gustan las funciones, puedes colocarlas en una categoría.

 16
Author: Jens Ayton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-06 22:15:20

Para decimales, al menos:

[[NSDecimalNumber notANumber] isEqualToNumber:myNumber]
 12
Author: Peter DeWeese,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-29 15:39:34

Para determinar si NSNumber es un NaN, conviértalo en un double 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 también desea verificar estos valores, es mejor usar isnormal() en su lugar:

NSLog( @"%d", isnormal(validNumber.doubleValue) ); // prints "1"
NSLog( @"%d", isnormal(nanNumber.doubleValue) ); // prints "0"
NSLog( @"%d", isnormal(posInfinity.doubleValue) ); // prints "0"
 10
Author: Jakob Egger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-15 19:01:48

Encontré que esto funciona, pero ¿es legal?

NSNumber *NaN = [NSDecimalNumber notANumber];

NSDecimalNumber *x = ... fill it somehow with NaN content ...

if ( x == NaN ) ... this works

¿Se garantiza que NaN sea un valor constante singleton? Sería genial, pero supongo que no lo es, ya que todos los ejemplos que encontré usan los métodos isEqual.

 8
Author: Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-03 20:26:17

También está la función isnan() que encontré hoy.

 5
Author: Johnny Mast,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-21 18:21:26

También podemos usar un #define definido en matemáticas.h as follws

if(isnan(myNumber))
{  // myNumber is NaN .

}

 2
Author: Mak083,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-04 07:20:11

Cualquier expresión booleana con NaN siempre devolverá false. ¿Pero cómo es eso útil?

Estaba recuperando a Nan de locationInView: mientras manejaba algunos gestos en una aplicación para iPhone. Y estaba muy contento de encontrar que cualquier expresión booleana con NaN siempre devolverá falso. Pongo esto para usar liek a continuación:

//Estaba usando el UIPanGestureRecognizer, y parece que en el RetoqUe obtendría Nan para la ubicación/.x - .y-bastante razonable ya que en este caso el final de un toque no tiene un ubicación.

CGPoint location = [gestureRecognizer locationInView:self];

if ( location.x != location.x || location.y != location.y )
{
 return;
}

Así que siempre.x y .y o valores flotantes legítimos, por supuesto que nunca no serán iguales a su propio valor. PERO en el caso de .x or .y siendo NaN, la comparación será falsa. Y puedo evitar con seguridad los cálculos con Nan.

 0
Author: Alan Morford,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-31 21:12:49

En realidad no hay tal objeto para NSNumber ya que si no es un número, entonces, bueno, no es un NSNumber. Es más habitual usar un objeto nil para representar esto.

 -2
Author: Mike Abdullah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-06 12:37:31