Je regardais le code source openjdk-1.7.0_25
et j'ai vu cette méthode:
/**
* 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 argument is NaN;
* {@code false} otherwise.
*/
static public boolean isNaN(float v) {
return (v != v);
}
Je ne comprends pas comment ça marche, quand cette méthode peut retourner true
?
Cette méthode peut retourner true pour certaines opérations, par exemple:
System.out.println(Float.isNaN(0.0f / 0.0f));
System.out.println(Double.isNaN(Math.sqrt(-1)));
NaN
représente une valeur indéfinie. La valeur de 0.0 / 0.0
est NaN
et Nan != NaN
. Cela peut sembler logique car Math.sqrt(-1)
vous donne également NaN
.
Voir le javadoc de Double.NaN
:
C'est équivalent à la valeur retournée par
Double.longBitsToDouble(0x7ff8000000000000L)
Et ensuite Double.longBitsToDouble()
:
Si l'argument est une valeur comprise entre
0x7ff0000000000001L
et0x7fffffffffffffffL
ou entre0xfff0000000000001L
et0xffffffffffffffffL
, le résultat estNaN
. Aucune opération à virgule flottante IEEE 754 fournie par Java ne permet de distinguer deux valeurs NaN du même type avec différents modèles de bits.
De Spécification du langage Java :
Le test d'égalité en virgule flottante est effectué conformément aux règles de la norme IEEE 754:
Si l'un des opérandes est NaN, alors le résultat de == est faux mais le résultat de! = Est vrai. En effet, le test x! = X est vrai si et seulement si la valeur de x est NaN. (Les méthodes Float.isNaN et Double.isNaN peuvent également être utilisées pour vérifier si une valeur est NaN.)
Le zéro positif et le zéro négatif sont considérés comme égaux. Par conséquent, -0.0 == 0.0 est vrai, par exemple.
Sinon, deux valeurs à virgule flottante distinctes sont considérées comme étant inégales par les opérateurs d'égalité. En particulier, il existe une valeur représentant l'infini positif et une valeur représentant l'infini négatif; chacun se compare égal à lui-même, et chaque comparaison est inégale à toutes les autres valeurs.
Parce que seul NaN compare faux avec lui-même. Donc, il retournera vrai lorsque vous passerez NaN
à la méthode.
Une comparaison avec NaN renvoie toujours un résultat non ordonné, même lorsque comparer avec lui-même. ... Les prédicats d'égalité et d'inégalité sont la non-signalisation donc x = x renvoyant false peut être utilisée pour tester si x est un NaN tranquille.
Il ne s’agit pas que de Java, c’est également vrai pour toutes les langues conformes au standard IEEE754.
Question connexe: Pourquoi Double.NaN == Double.NaN renvoie-t-il false?
Simple .. Nan
est toujours ! =NaN
, ces valeurs ne sont égales à rien. Voir this :
Comme cela a déjà été décrit, NaN est non ordonné, donc numérique Une opération de comparaison impliquant un ou deux NaNs renvoie false et any ! = la comparaison impliquant NaN renvoie true, y compris x! = x lorsque x est NaN.
Donc, tester si v != v
est suffisant pour dire si value
est NaN
ou non.
Autant que je sache La valeur NaN n’est égale à rien. Ainsi, lorsque vous avez passé float v
, il n’est jamais différent de lui-même.