Déterminer si NSNumber est NaN

Comment puis-je déterminer si un NSNumber de cacao représente NaN (pas un nombre)?

Cela se produit, par exemple, lorsque j’parsing une chaîne dont le contenu est non valide (non numérique).

Donc, j’ai découvert que la propriété de classe [NSDecimalNumber notANumber] est juste pour cela. Dans certaines langues, NaN! = NaN, mais ce n’est pas le cas dans Cocoa.

Comme le dit Mike Abdullah, la manière naturelle de représenter un NaN dans Cocoa est avec nil , mais [NSNumber numberWithDouble:NAN] renvoie un object valide. Il n’y a pas de NSNumber spécifique de détecter NSNumber , mais la manière générale, isnan([foo doubleValue]) , fonctionne. Si vous n’aimez pas les fonctions, vous pouvez le coller dans une catégorie.

Pour les décimales, au moins:

 [[NSDecimalNumber notANumber] isEqualToNumber:myNumber] 

Pour déterminer si NSNumber est un NaN, convertissez-le en double et utilisez la fonction 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" 

Cependant, vous devriez faire attention, car il existe d’autres valeurs spéciales, par exemple:

 NSNumber *posInfinity = [NSNumber numberWithDouble: 1./0.]; NSLog( @"%d", isnan(posInfinity.doubleValue) ); // prints "0" 

Si vous souhaitez également vérifier ces valeurs, il est préférable d’utiliser isnormal() place:

 NSLog( @"%d", isnormal(validNumber.doubleValue) ); // prints "1" NSLog( @"%d", isnormal(nanNumber.doubleValue) ); // prints "0" NSLog( @"%d", isnormal(posInfinity.doubleValue) ); // prints "0" 

J’ai trouvé que cela fonctionne, mais est-ce légal?

 NSNumber *NaN = [NSDecimalNumber notANumber]; NSDecimalNumber *x = ... fill it somehow with NaN content ... if ( x == NaN ) ... this works 

NaN est-il garanti d’être une valeur constante singleton ? Serait cool, mais je suppose que non, puisque tous les exemples que j’ai trouvés utilisent les méthodes isEqual .

il y a aussi la fonction isnan () je l’ai trouvé aujourd’hui.

On peut aussi utiliser un #define défini en math.h comme suit

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

}

Toute expression booléenne avec NaN renverra toujours false. Mais comment est-ce utile?

Je récupérais Nan de locationInView: tout en manipulant des gestes dans une application iPhone. Et a été très heureux de constater que toute expression booléenne avec NaN renverra toujours false. Je mets ça pour utiliser liek ci-dessous:

// J’utilisais UIPanGestureRecognizer , et semble que sur TouchUp j’aurais Nan pour / location .x – .y – assez raisonnable car dans ce cas la fin d’une touche n’a pas d’emplacement.

 CGPoint location = [gestureRecognizer locationInView:self]; if ( location.x != location.x || location.y != location.y ) { return; } 

Donc, comme les valeurs de flottement longues .x et .y ou légitimes, bien sûr, elles ne seront jamais égales à leur propre valeur. MAIS dans le cas où .x ou .y étant NaN, la comparaison sera fausse. Et je peux éviter en toute sécurité les calculs avec Nan.

Il n’y a pas vraiment d’object pour NSNumber puisque si ce n’est pas un nombre, alors, eh bien, ce n’est pas un NSNumber. Il est plus courant d’utiliser un object nul pour le représenter.