web-dev-qa-db-fra.com

Java isNan comment ça marche?

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?

16
rascio

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 et 0x7fffffffffffffffL ou entre 0xfff0000000000001L et 0xffffffffffffffffL, le résultat est NaN. 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.

19
Rohit Jain

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.

3
axtavt

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. 

La source 

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?

2
xyz

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.

1
Maroun

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.

0
Suresh Atta