¿Cómo puedo determinar si un NSNumber de Cocoa representa NaN (no un número)?Determine si NSNumber es NaN
Esto surge, por ejemplo, cuando analizo una cadena que tiene un contenido inválido (no numérico).
¿Cómo puedo determinar si un NSNumber de Cocoa representa NaN (no un número)?Determine si NSNumber es NaN
Esto surge, por ejemplo, cuando analizo una cadena que tiene un contenido inválido (no numérico).
Así que 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.
No existe realmente 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.
Como dice Mike Abdullah, la forma natural de representar un NaN en Cocoa es con nil
, pero [NSNumber numberWithDouble:NAN]
devuelve un objeto válido. No hay ninguna forma específica de detectar esto, NSNumber
, pero la manera general, isnan([foo doubleValue])
, funciona. Si no le gustan las funciones, puede pegarlas en una categoría.
Hola chicos: estoy bastante seguro de que nada no significa lo mismo que NaN. Nada significa ningún valor en absoluto. NaN se usa para representar el resultado de ciertas operaciones de coma flotante (dividiendo por cero, por ejemplo) ... así que realmente NaN ES un número ... Es el número "No es un número" ... – nielsbot
Sí, lo sabemos. El punto es que 'nil' es la forma natural de representar cosas como una cadena con constantes no numéricas, como en el ejemplo del PO. –
también está la función isnan() la encontré hoy.
Cualquier expresión booleana con NaN siempre devolverá falso. Pero, ¿cómo es eso útil?
Estaba sacando 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 la/ubicación .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;
}
Entonces valores flotantes legítimos, siempre .xy .y o, por supuesto, nunca habrá no es igual a no 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.
para decimales, por lo menos:
[[NSDecimalNumber notANumber] isEqualToNumber:myNumber]
He encontrado que esto funciona, pero ¿es legal?
NSNumber *NaN = [NSDecimalNumber notANumber];
NSDecimalNumber *x = ... fill it somehow with NaN content ...
if (x == NaN) ... this works
es NaN
garantizada a ser un valor constante singleton
? Sería genial, pero supongo que no, ya que todos los ejemplos que encontré usan los métodos isEqual
.
Claro, ninguna palabra 'singleton' en la documentación parece necesitar isEqual-ish all checks. (( – dmitrynikolaev
NaN no es un valor único: hay variantes, incluido NaN "silencioso" y NaN de "señalización", y la definición de codificación permite que algunos bits irrelevantes (por ejemplo, signo) tengan cualquier valor. Por esta razón == NAN no puede ser Confiamos en. –
Seguramente es singleton detrás de las escenas, pero aún así es mejor usar sEqual en caso de que este comportamiento cambie en el futuro. – Andy
Para determinar si NSNumber es un NaN, convertirlo en un doble y utilizar 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, hay que tener cuidado, porque hay otros valores especiales, por ejemplo:
NSNumber *posInfinity = [NSNumber numberWithDouble: 1./0.];
NSLog(@"%d", isnan(posInfinity.doubleValue)); // prints "0"
Si desea comprobar si estos valores, así, es mejor utilizar isnormal()
lugar:
NSLog(@"%d", isnormal(validNumber.doubleValue)); // prints "1"
NSLog(@"%d", isnormal(nanNumber.doubleValue)); // prints "0"
NSLog(@"%d", isnormal(posInfinity.doubleValue)); // prints "0"
Vale la pena señalar que 'isnormal (0)' devuelve 0 (igual que 'isnormal (NAN)') , entonces si cero es un valor potencialmente válido, compruebe tanto 'inan' como 'isinf' en su lugar.' isfinite() 'es una mejor opción. – Demitri
También podemos usar un #define definido en matemáticas.h como follws
if(isnan(myNumber))
{ // myNumber is NaN .
}
Esta solución funciona con tipos de datos primitivos y no con objetos NSNumber directamente, tiene que obtener el valor de NSNumber, ejemplo: number.intValue – ObjSal
Sólo para mayor claridad, para probar si un NSNumber es NaN entonces el código sería: '[NSNumber isEqualToNumber: [NSDecimalNumber NotANumber]]'. Esto devuelve SÍ si el NSNumber es NaN. – SimonB