Pourquoi ne Double.Nan = = Double.NaN return false?

j'étudiais juste les questions OCPJP et j'ai trouvé ce code étrange:

public static void main(String a[]) {
    System.out.println(Double.NaN==Double.NaN);
    System.out.println(Double.NaN!=Double.NaN);
}

quand j'ai lancé le code, j'ai eu:

false
true

Comment est la sortie false quand nous comparons deux choses qui se ressemblent? Que signifie NaN ?

144
demandé sur Pops 2012-01-11 17:02:30

9 réponses

NaN signifie "pas un nombre".

Java Language Specification (JLS) Third Edition says :

une opération qui déborde produit un infini signé, une opération qui déborde produit une valeur dénormalisée ou un zéro signé, et une opération qui n'a aucun résultat mathématiquement défini produit NaN. Toutes les opérations numériques avec NaN comme opérande produisent NaN comme résultat. Comme il a déjà été décrit, NaN est non classé , donc une opération de comparaison numérique impliquant un ou deux Nans retourne false et toute != comparaison impliquant Nan retourne true , y compris x!=x quand x est NaN.

131
répondu Adrian Mitev 2015-12-30 16:37:57

NaN est, par définition, n'est pas égale à un nombre quelconque, y compris NaN. Ceci fait partie de la norme IEEE 754 et mis en œuvre par le CPU/FPU. Ce N'est pas quelque chose que la JVM doit ajouter de la logique au support.

http://en.wikipedia.org/wiki/NaN

une comparaison avec une NaN renvoie toujours un résultat sans ordre même en se comparant avec lui-même. ... Les prédicats d'égalité et d'inégalité sont non-signalants donc x = x retourner false peut être utilisé pour tester si x est une Nan calme.

Java traite toutes les NaN comme des Nan tranquilles.

60
répondu Peter Lawrey 2012-01-11 14:04:35

pourquoi cette logique

NaN signifie Not a Number . Ce n'est pas un nombre? Quoi. Vous pouvez avoir tout dans un côté et rien de l'autre côté, rien ne garantit que les deux sont égaux. NaN est calculé avec Double.longBitsToDouble(0x7ff8000000000000L) et comme vous pouvez le voir dans la documentation de longBitsToDouble :

si l'argument est n'importe quelle valeur dans la gamme 0x7ff0000000000001L par 0x7fffffffffffffffL ou dans la gamme 0xfff0000000000001L à travers 0xffffffffffffffffL , le résultat est un NaN .

aussi, NaN est logiquement traité à l'intérieur de L'API.


Documentation

/** 
 * A constant holding a Not-a-Number (NaN) value of type
 * {@code double}. It is equivalent to the value returned by
 * {@code Double.longBitsToDouble(0x7ff8000000000000L)}.
 */
public static final double NaN = 0.0d / 0.0;

Par la façon dont, NaN est testé en tant que votre échantillon de code:

/**
 * Returns {@code true} if the specified number is a
 * Not-a-Number (NaN) value, {@code false} otherwise.
 *
 * @param   v   the value to be tested.
 * @return  {@code true} if the value of the argument is NaN;
 *          {@code false} otherwise.
 */
static public boolean isNaN(double v) {
    return (v != v);
}

Solution

ce que vous pouvez faire est d'utiliser compare / compareTo :

Double.NaN est considéré par cette méthode comme étant égal à lui-même et supérieure à toutes les autres valeurs double (y compris Double.POSITIVE_INFINITY ).

Double.compare(Double.NaN, Double.NaN);
Double.NaN.compareTo(Double.NaN);

Ou, equals :

si this et argument les deux représentent Double.NaN , alors la méthode equals retourne true , bien que Double.NaN==Double.NaN a la valeur false .

Double.NaN.equals(Double.NaN);
48
répondu falsarella 2015-05-27 14:26:03

ce n'est peut-être pas une réponse directe à la question. Mais si vous voulez vérifier si quelque chose est égal à Double.NaN , vous devez utiliser ceci:

double d = Double.NaN
Double.isNaN(d);

Ce sera le retour de true

10
répondu JREN 2015-10-01 14:08:30

NaN est une valeur spéciale qui dénote "pas un nombre"; c'est le résultat de certaines opérations arithmétiques invalides, telles que sqrt(-1) , et a la propriété (parfois ennuyeuse) que NaN != NaN .

3
répondu Fred Foo 2012-01-11 13:04:10

que par, La norme IEEE pour l'arithmétique à virgule flottante pour les nombres Double Précision,

de L'IEEE en virgule flottante double précision représentation standard exige un mot de 64 bits, qui peut être représenté comme numéroté de 0 à 63, de gauche à droite

enter image description here où,

S: Sign – 1 bit
E: Exponent – 11 bits
F: Fraction – 52 bits 

si E=2047 (tous E sont 1 ) et F est non zéro, puis V=NaN ("pas un nombre")

ce qui signifie,

si tous les bits de E sont 1, et s'il y a un bit non nul dans F alors le nombre est NaN .

donc, entre autres, tous les numéros suivants sont NaN ,

0 11111111 0000000000000000010000000000000000000000000000000000 = NaN
1 11111111 0000010000000000010001000000000000001000000000000000 = NaN
1 11111111 0000010000011000010001000000000000001000000000000000 = NaN

en particulier, vous ne pouvez pas tester

if (x == Double.NaN) 

pour vérifier si un résultat donné est égal à Double.NaN , car toutes les valeurs" non un nombre " sont considérées comme distinctes. Cependant, vous pouvez utiliser la méthode Double.isNaN :

if (Double.isNaN(x)) // check whether x is "not a number"
3
répondu Sufiyan Ghori 2015-01-31 10:29:04

Pas un nombre représente le résultat des opérations dont le résultat n'est pas représentable par un nombre. L'opération la plus célèbre est 0/0, dont le résultat n'est pas connu.

pour cette raison, NaN n'est pas égal à quoi que ce soit (y compris d'autres valeurs non numériques). Pour plus d'informations, il suffit de consulter la page wikipedia: http://en.wikipedia.org/wiki/NaN

2
répondu Matteo 2012-01-12 12:04:48

selon ce lien , il a diverses situations et difficile à se rappeler. C'est ainsi que je m'en souviens et que je les distingue. NaN signifie " mathématiquement Non défini "par exemple:" le résultat de 0 divisé par 0 est non défini "et parce qu'il est non défini, donc"la comparaison liée à non défini est bien sûr non défini". En outre, il fonctionne plus comme mathématique locaux. D'autre part, l'infini positif et négatif est prédéfini et définitif, pour exemple "positif ou négatif infini grand est bien défini mathématiquement".

0
répondu Tiina 2018-02-26 02:32:23