web-dev-qa-db-fra.com

Float.NaN == Float.NaN

Pourquoi cette comparaison me donne "faux"? J'ai regardé la source et Float.NaN est défini comme 

/** 
 * A constant holding a Not-a-Number (NaN) value of type
 * <code>float</code>.  It is equivalent to the value returned by
 * <code>Float.intBitsToFloat(0x7fc00000)</code>.
 */
public static final float NaN = 0.0f / 0.0f;

EDIT: étonnamment, si je fais cela:

System.out.println("FC " + (Float.compare(Float.NaN, Float.NaN)));

cela me donne 0. Donc, Float.compare() pense que NaN est égal à lui-même!

27
shrini1000

Parce que Java implémente le standard de virgule flottante IEEE-754 qui garantit que toute comparaison avec NaN renverra false (sauf != qui renverra true)

Cela signifie que vous ne pouvez pas vérifier de la manière habituelle si un nombre à virgule flottante est NaN. Vous pouvez donc réinterpréter les deux nombres en tant que nombres entiers et les comparer ou utiliser la solution beaucoup plus intelligente:

def isNan(val):
     return val != val
35
Voo

Utilisez Float.isNaN pour vérifier les valeurs NaN.

61
pencil

Tout ce que j'ai à dire, c'est: Wikipedia à propos de NaN .

C'est écrit assez clairement. La partie intéressante est que la virgule flottante NaN du standard commun exprime un NaN de la manière suivante: 

s111 1111 1xxx xxxx xxxx xxxx xxxx xxxx

Le s est le signe (négatif ou positif), le 1 est l'exposant et le x est considéré comme une charge utile.

En regardant la charge utile, un NaN n'est pas égal à un NaN et il existe de rares chances que ces informations de la charge utile vous intéressent en tant que développeur (par exemple, des nombres complexes).

Une autre chose est que dans la norme ils ont la signalisation et tout à fait NaN. Un NaN de signalisation (sNaN) signifie un NaN qui devrait déclencher une réaction comme une exception. Il devrait être utilisé pour dire à haute voix que vous avez un problème dans votre équation. Un NaN silencieux (qNaN) est un NaN transmis silencieusement. 

Un sNaN qui a créé un signal est converti en un qNaN pour ne plus produire d'autres signaux lors d'opérations ultérieures. N'oubliez pas qu'un système définit i ^ 0 = 1 comme une constante que NaN ^ 0 = 1 reste vrai. Il existe donc des cas où les gens calculent avec NaN.

Donc à la fin, je voudrais aller avec ceci: qNaN! = SNaN mais ceci est interne et n'est pas observable pour l'utilisateur (vous ne pouvez pas vérifier cela). Mélangez le long du paiement et du signe (oui, vous pouvez avoir NaN négatif et positif) et il me semble que toujours retourner NaN! = NaN ressemble à un choix beaucoup plus sage que j'ai finalement appris à apprécier -> Je ne me plaindrai jamais ni ne me demander à propos de l'inégalité de NaN à nouveau. Féliciter les gens qui ont été si attentionné nous donner un si bon niveau!

Au fait: Java utilise un NaN positif avec une charge utile de 0 (tous les x sont des zéros).

0
Martin Kersten