Frage
Ich habe ein Programm, dass versucht, ein double
auf eine gewünschte Zahl zu schrumpfen. Der Ausgang ich erhalte, ist NaN
.
Was bedeutet NaN
Mittelwert in Java?
Lösung
Genommen von dieser Seite :
„NaN“ steht für „keine Zahl“. "Nan" wenn ein Gleitkomma hergestellt wird Betrieb hat einige Eingabeparameter dass Ursache der Operation zu erzeugen, einige undefiniert Ergebnis. Beispielsweise, 0.0 durch 0,0 geteilt wird arithmetisch undefiniert. Unter der Quadratwurzel aus einem negative Zahl ist auch nicht definiert.
Andere Tipps
NaN
Mittel „Not a Number“ und ist im Grunde eine Darstellung eines speziellen Fließkommawert in der IEE 754 Floating-Point- Standard. NaN im Allgemeinen bedeutet, dass der Wert etwas, das nicht mit einem gültigen Gleitkommazahl ausgedrückt werden kann.
Eine Umwandlung in diesem Wert führen wird, wenn der Wert Wesen umgewandelt etwas anderes, zum Beispiel, wenn eine Zeichenfolge umgewandelt werden, die keine Zahl darstellt.
NaN
bedeutet „keine Zahl“, und ist das Ergebnis nicht definiert Operationen an Gleitkommazahlen wie beispielsweise Null durch Null geteilt wird. (Beachten Sie, dass, während eine von Null verschiedene Zahl durch Null dividiert wird auch in der Regel in der Mathematik nicht definiert, es ist nicht in NaN führt aber in positive oder negative Unendlichkeit).
NaN
bedeutet "keine Zahl." Es ist ein besonderer Gleitkommawert das bedeutet, dass das Ergebnis einer Operation nicht definiert wurde oder nicht darstellbare als reelle Zahl.
Siehe hier für weitere Erklärung dieses Wertes.
NaN steht für keine Zahl. Es wird verwendet, jeden Wert, um anzuzeigen, die mathematisch nicht definiert ist. Wie 0.0 von 0,0 geteilt wird. Sie können sich für weitere Informationen hier: https://web.archive.org/web/20120819091816/http://www.concentric.net/~ttwang/tech/javafloat.htm
Post Ihr Programm hier, wenn Sie weitere Hilfe benötigen.
NaN = Not a Number.
Die Mittel keine Zahl. Es ist eine allgemeine Darstellung für einen unmöglichen numerischen Wert in vielen Programmiersprachen.
Nicht ein Java Kerl, aber in JS und anderen Sprachen benutze ich es der "Not a Number", also eine Operation verursachte es keine gültige Zahl werden.
Es bedeutet wörtlich "Not a Number". Ich vermute, dass etwas falsch ist mit Ihrem Umwandlungsprozess.
Überprüfen Sie die Not A Number Abschnitt aus unter dieser Referenz
Keine gültige Gleitkommawert (beispielsweise das Ergebnis der Division durch Null)
Minimal runnable Beispiel
Das erste, was Sie wissen müssen, ist, dass das Konzept von NaN auf der CPU-Hardware direkt umgesetzt wird.
All wichtiger moderner CPUs scheint IEEE 754 , die angibt, Gleitkomma-Formate und NaNs , das sind nur spezielle float-Werte, einen Teil dieser Norm ist.
Aus diesem Grund wird das Konzept in jeder Sprache die sehr ähnlich sein, einschließlich Java, die nur Code Gleitkomma emittiert direkt in die CPU.
Bevor Sie fortfahren, möchten Sie vielleicht zunächst die folgenden Antworten lesen, die ich geschrieben habe:
- eine kurze Auffrischung des IEEE 754 Floating-Point-Format: Was ist ein subnormal Gleitkommazahl?
- einige untere Ebene NaN Grundlagen abgedeckt mit C / C ++: Was ist der Unterschied zwischen ruhigen NaN und Signal NaN?
Jetzt für einige Java Aktion. Die meisten Funktionen von Interesse, die nicht in der Kernsprache leben im Inneren sind 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));
}
}
Führen Sie mit:
javac Nan.java && java -ea Nan
Ausgabe:
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
So daraus lernen wir ein paar Dinge:
-
seltsam schwebende Operationen, die NaN kein vernünftiges Ergebnis geben haben:
-
0.0f / 0.0f
-
sqrt(-1.0f)
-
log(-1.0f)
erzeugen eine
NaN
.In C ist es tatsächlich möglich, Signale Anfrage auf solchen Operationen mit
feenableexcept
angehoben werden, um sie zu erkennen, aber ich glaube nicht, dass in Java ausgesetzt ist: Warum integer-Division durch Null 1 / 0 gibt Fehler aber Gleitkomma-1 / 0.0 gibt "Inf"? -
-
seltsame Vorgänge, die an der Grenze von entweder plus oder minus unendlich jedoch nicht geben + - unendlich statt NaN
-
1.0f / 0.0f
-
log(0.0f)
0.0
fast fällt in dieser Kategorie, aber wahrscheinlich das Problem ist, dass es entweder zu plus oder minus unendlich gehen könnte, so dass es als NaN verlassen wurde. -
-
, wenn der Eingang NaN einen schwimmenden Betrieb ist, der Ausgang neigt auch NaN
zu sein,
-
gibt es mehrere mögliche Werte für NaN
0x7fc00000
,0x7fc00001
,0x7fc00002
, obwohl x86_64 nur0x7fc00000
zu erzeugen scheint. -
NaN und unendlich haben ähnliche binäre Darstellung.
Lassen Sie uns Bruchs ein paar von ihnen:
nan = 0x7fc00000 = 0 11111111 10000000000000000000000 positive_inf = 0x7f800000 = 0 11111111 00000000000000000000000 negative_inf = 0xff800000 = 1 11111111 00000000000000000000000 | | | | | mantissa | exponent | sign
Von diesem wir bestätigen, was IEEE754 gibt an:
- beide NaN und Unendlichkeiten haben Exponent == 255 (alle Einsen)
- Unendlichkeiten have Mantisse == 0. Es gibt also nur zwei mögliche Unendlichkeiten: + und - durch das Vorzeichenbit differenziert
- NaN hat Mantisse! = 0. Es gibt also mehrere Möglichkeiten, mit Ausnahme der Mantisse == 0 die Unendlichkeit
-
NaNs kann entweder positiv oder negativ (oben Bit) sein, obwohl es dies keine Auswirkungen auf den normalen Betrieb hat
Getestet in Ubuntu 18.10 amd64, OpenJDK 1.8.0_191.