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
?
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 retournetrue
, y comprisx!=x
quandx
est NaN.
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.
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
par0x7fffffffffffffffL
ou dans la gamme0xfff0000000000001L
à travers0xffffffffffffffffL
, le résultat est unNaN
.
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 valeursdouble
(y comprisDouble.POSITIVE_INFINITY
).
Double.compare(Double.NaN, Double.NaN);
Double.NaN.compareTo(Double.NaN);
Ou, equals
:
si
this
etargument
les deux représententDouble.NaN
, alors la méthodeequals
retournetrue
, bien queDouble.NaN==Double.NaN
a la valeurfalse
.
Double.NaN.equals(Double.NaN);
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
le javadoc pour Double.NaN 151970920" en dit long:
Une tenue constante qui n'est Pas un Nombre (NaN) valeur de type
double
. Il est équivalent à la valeur retournée parDouble.longBitsToDouble(0x7ff8000000000000L)
.
fait intéressant, la source de Double
définit NaN
ainsi:
public static final double NaN = 0.0d / 0.0;
le comportement spécial que vous décrivez est câblé dans la JVM.
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
.
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
où,
S: Sign – 1 bit
E: Exponent – 11 bits
F: Fraction – 52 bits
si
E=2047
(tousE
sont1
) etF
est non zéro, puisV=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"
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
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".