J'ai un programme qui essaie de réduire un double
nombre souhaité. Le résultat que j'obtiens est NaN
.
Que NaN
signifie Java?
J'ai un programme qui essaie de réduire un double
nombre souhaité. Le résultat que j'obtiens est NaN
.
Que NaN
signifie Java?
Réponses:
Tiré de cette page :
"NaN" signifie "pas un nombre". "Nan" est produit si une opération en virgule flottante a des paramètres d'entrée qui amènent l'opération à produire un résultat non défini. Par exemple, 0,0 divisé par 0,0 est arithmétiquement indéfini. Prendre la racine carrée d'un nombre négatif est également indéfini.
NaN
a la propriété intéressante d'être le seul "nombre" qui n'est pas le même que lui-même une fois comparé. Par conséquent , une commune (et dans de nombreuses langues le seul) test si un nombre x
est NaN
le suivant:boolean isNaN(x){return x != x;}
i
et certains langages comme python le traitent très bien ... Ce n'est peut-être pas le cas chez java
toi
NaN
signifie «Pas un nombre» et est essentiellement une représentation d'une valeur à virgule flottante spéciale dans la norme à virgule flottante IEE 754 . NaN signifie généralement que la valeur est quelque chose qui ne peut pas être exprimé avec un nombre à virgule flottante valide.
Une conversion aboutira à cette valeur, lorsque la valeur à convertir est autre chose, par exemple lors de la conversion d'une chaîne qui ne représente pas un nombre.
parseFloat()
ou parseDouble
? Ou autre chose?
NaN
signifie "Pas un nombre" et est le résultat d'opérations non définies sur les nombres à virgule flottante comme par exemple la division de zéro par zéro. (Notez que si la division d'un nombre non nul par zéro est également généralement indéfinie en mathématiques, cela ne se traduit pas par NaN mais par l'infini positif ou négatif).
NaN
signifie «Pas un nombre». C'est une valeur à virgule flottante spéciale qui signifie que le résultat d'une opération n'a pas été défini ou ne peut pas être représenté en tant que nombre réel.
Voir ici pour plus d'explications sur cette valeur.
NaN signifie Pas un nombre. Il est utilisé pour signifier toute valeur non définie mathématiquement. Comme diviser 0,0 par 0,0. Vous pouvez chercher ici pour plus d'informations: https://web.archive.org/web/20120819091816/http://www.concentric.net/~ttwang/tech/javafloat.htm
Publiez votre programme ici si vous avez besoin d'aide supplémentaire.
NaN = pas un nombre.
Exemple exécutable minimal
La première chose que vous devez savoir, c'est que le concept de NaN est implémenté directement sur le matériel du CPU.
Tous les principaux processeurs modernes semblent suivre IEEE 754 qui spécifie les formats à virgule flottante, et les NaN, qui ne sont que des valeurs flottantes spéciales, font partie de cette norme.
Par conséquent, le concept sera très similaire dans tous les langages, y compris Java qui émet simplement du code en virgule flottante directement vers le processeur.
Avant de continuer, vous voudrez peut-être lire d'abord les réponses suivantes que j'ai écrites:
Maintenant, pour une action Java. La plupart des fonctions d'intérêt qui ne sont pas dans le langage de base vivent à l'intérieur java.lang.Float
.
Nan.java
import java.lang.Float;
import java.lang.Math;
public class Nan {
public static void main(String[] args) {
// Generate some NaNs.
float nan = Float.NaN;
float zero_div_zero = 0.0f / 0.0f;
float sqrt_negative = (float)Math.sqrt(-1.0);
float log_negative = (float)Math.log(-1.0);
float inf_minus_inf = Float.POSITIVE_INFINITY - Float.POSITIVE_INFINITY;
float inf_times_zero = Float.POSITIVE_INFINITY * 0.0f;
float quiet_nan1 = Float.intBitsToFloat(0x7fc00001);
float quiet_nan2 = Float.intBitsToFloat(0x7fc00002);
float signaling_nan1 = Float.intBitsToFloat(0x7fa00001);
float signaling_nan2 = Float.intBitsToFloat(0x7fa00002);
float nan_minus = -nan;
// Generate some infinities.
float positive_inf = Float.POSITIVE_INFINITY;
float negative_inf = Float.NEGATIVE_INFINITY;
float one_div_zero = 1.0f / 0.0f;
float log_zero = (float)Math.log(0.0);
// Double check that they are actually NaNs.
assert Float.isNaN(nan);
assert Float.isNaN(zero_div_zero);
assert Float.isNaN(sqrt_negative);
assert Float.isNaN(inf_minus_inf);
assert Float.isNaN(inf_times_zero);
assert Float.isNaN(quiet_nan1);
assert Float.isNaN(quiet_nan2);
assert Float.isNaN(signaling_nan1);
assert Float.isNaN(signaling_nan2);
assert Float.isNaN(nan_minus);
assert Float.isNaN(log_negative);
// Double check that they are infinities.
assert Float.isInfinite(positive_inf);
assert Float.isInfinite(negative_inf);
assert !Float.isNaN(positive_inf);
assert !Float.isNaN(negative_inf);
assert one_div_zero == positive_inf;
assert log_zero == negative_inf;
// Double check infinities.
// See what they look like.
System.out.printf("nan 0x%08x %f\n", Float.floatToRawIntBits(nan ), nan );
System.out.printf("zero_div_zero 0x%08x %f\n", Float.floatToRawIntBits(zero_div_zero ), zero_div_zero );
System.out.printf("sqrt_negative 0x%08x %f\n", Float.floatToRawIntBits(sqrt_negative ), sqrt_negative );
System.out.printf("log_negative 0x%08x %f\n", Float.floatToRawIntBits(log_negative ), log_negative );
System.out.printf("inf_minus_inf 0x%08x %f\n", Float.floatToRawIntBits(inf_minus_inf ), inf_minus_inf );
System.out.printf("inf_times_zero 0x%08x %f\n", Float.floatToRawIntBits(inf_times_zero), inf_times_zero);
System.out.printf("quiet_nan1 0x%08x %f\n", Float.floatToRawIntBits(quiet_nan1 ), quiet_nan1 );
System.out.printf("quiet_nan2 0x%08x %f\n", Float.floatToRawIntBits(quiet_nan2 ), quiet_nan2 );
System.out.printf("signaling_nan1 0x%08x %f\n", Float.floatToRawIntBits(signaling_nan1), signaling_nan1);
System.out.printf("signaling_nan2 0x%08x %f\n", Float.floatToRawIntBits(signaling_nan2), signaling_nan2);
System.out.printf("nan_minus 0x%08x %f\n", Float.floatToRawIntBits(nan_minus ), nan_minus );
System.out.printf("positive_inf 0x%08x %f\n", Float.floatToRawIntBits(positive_inf ), positive_inf );
System.out.printf("negative_inf 0x%08x %f\n", Float.floatToRawIntBits(negative_inf ), negative_inf );
System.out.printf("one_div_zero 0x%08x %f\n", Float.floatToRawIntBits(one_div_zero ), one_div_zero );
System.out.printf("log_zero 0x%08x %f\n", Float.floatToRawIntBits(log_zero ), log_zero );
// NaN comparisons always fail.
// Therefore, all tests that we will do afterwards will be just isNaN.
assert !(1.0f < nan);
assert !(1.0f == nan);
assert !(1.0f > nan);
assert !(nan == nan);
// NaN propagate through most operations.
assert Float.isNaN(nan + 1.0f);
assert Float.isNaN(1.0f + nan);
assert Float.isNaN(nan + nan);
assert Float.isNaN(nan / 1.0f);
assert Float.isNaN(1.0f / nan);
assert Float.isNaN((float)Math.sqrt((double)nan));
}
}
Courir avec:
javac Nan.java && java -ea Nan
Production:
nan 0x7fc00000 NaN
zero_div_zero 0x7fc00000 NaN
sqrt_negative 0xffc00000 NaN
log_negative 0xffc00000 NaN
inf_minus_inf 0x7fc00000 NaN
inf_times_zero 0x7fc00000 NaN
quiet_nan1 0x7fc00001 NaN
quiet_nan2 0x7fc00002 NaN
signaling_nan1 0x7fa00001 NaN
signaling_nan2 0x7fa00002 NaN
nan_minus 0xffc00000 NaN
positive_inf 0x7f800000 Infinity
negative_inf 0xff800000 -Infinity
one_div_zero 0x7f800000 Infinity
log_zero 0xff800000 -Infinity
Nous apprenons donc quelques choses:
des opérations flottantes étranges qui n'ont aucun résultat raisonnable donnent NaN:
0.0f / 0.0f
sqrt(-1.0f)
log(-1.0f)
générer un NaN
.
En C, il est en fait possible de demander des signaux à lever sur de telles opérations avec feenableexcept
pour les détecter, mais je ne pense pas que cela soit exposé en Java: Pourquoi la division entière par zéro 1/0 donne-t-elle une erreur mais une virgule flottante 1 / 0,0 renvoie "Inf"?
les opérations étranges qui sont à la limite de l'infini plus ou moins donnent cependant + - infini au lieu de NaN
1.0f / 0.0f
log(0.0f)
0.0
tombe presque dans cette catégorie, mais le problème est probablement qu'il pourrait aller à plus ou moins l'infini, donc il a été laissé comme NaN.
si NaN est l'entrée d'une opération flottante, la sortie a également tendance à être NaN
il y a plusieurs valeurs possibles pour NaN 0x7fc00000
, 0x7fc00001
, 0x7fc00002
, bien que x86_64 semble générer seulement 0x7fc00000
.
NaN et l'infini ont une représentation binaire similaire.
Décomposons-en quelques-uns:
nan = 0x7fc00000 = 0 11111111 10000000000000000000000
positive_inf = 0x7f800000 = 0 11111111 00000000000000000000000
negative_inf = 0xff800000 = 1 11111111 00000000000000000000000
| | |
| | mantissa
| exponent
|
sign
À partir de là, nous confirmons ce que IEEE754 spécifie:
Les NaN peuvent être positifs ou négatifs (bit du haut), bien que cela n'ait aucun effet sur les opérations normales
Testé dans Ubuntu 18.10 amd64, OpenJDK 1.8.0_191.
Pas un gars de Java, mais dans JS et d'autres langages, j'utilise "Pas un nombre", ce qui signifie qu'une opération a fait en sorte qu'il ne devienne pas un nombre valide.
Cela signifie littéralement «Pas un nombre». Je soupçonne que quelque chose ne va pas avec votre processus de conversion.
Consultez la section Not A Number à cette référence
Pas une valeur à virgule flottante valide (par exemple, le résultat de la division par zéro)