Java:Das Hinzufügen von Double.MIN_NORMAL zu einem Double ändert die Zahl nicht
-
21-12-2019 - |
Frage
Ich dachte, dass MIN_NORMAL ein Wert wäre, den man zu einem „normalen“ Double addieren könnte und die Zahl würde sich ändern.Z.B.Füge Double.MIN_NORMAL zu 0,1d hinzu und du erhältst einen anderen Wert als 0,1d, allerdings ist mein Verständnis falsch:
public static void test(double val) {
if (val == (val - Double.MIN_NORMAL*1e50d))
System.out.printf("val == (val - Double.MIN_NORMAL*1e50d) for val=%.20f\n", val);
else
System.out.printf("val != (val - Double.MIN_NORMAL*1e50d) for val=%.20f\n", val);
}
Was ergibt:
test(0.0d);
> val != (val - Double.MIN_NORMAL*1e50d) for val=0.00000000000000000000
test(1.0d);
> val == (val - Double.MIN_NORMAL*1e50d) for val=1.00000000000000000000
test(0.1d);
> val == (val - Double.MIN_NORMAL*1e50d) for val=0.10000000000000000000
Bitte erklären Sie mir hier, was meiner Logik widerspricht: Selbst wenn ich MIN_NORMAL mal 1e50d addiere, erhalte ich immer noch die gleiche Zahl.
Ich habe Binärdarstellungen überprüft und 1 * Double.MIN_NORMAL unterscheidet sich von 2 * Double.MIN_NORMAL, aber wenn man diese von irgendetwas außer Null subtrahiert, ändert sich die ursprüngliche Zahl nicht.
Lösung
MIN_NORMAL
ist, wie das Javadoc sagt, nur das kleinste normalisierte double
Wert.Das heißt aber nicht, dass es so etwas ist 1
für int
S:Für Gleitkommawerte gilt dies einfach NEIN Standard „eps“, das Sie hinzufügen können, um zum nächsten darstellbaren Wert zu wechseln – das „eps“ hängt immer vom Exponenten des angegebenen Gleitkommawerts ab.Deshalb heißen sie schwebend Punkte, am Ende :)
Java 1.6+ bietet jedoch Math.nextAfter()
was für jeden gegebenen Wert zurückkommt double
, das nächste oder vorherige Darstellbare double
.
Bei älteren Java-Versionen können Sie jederzeit herumspielen Double.doubleToLongBits()
, das Ergebnis inkrementieren oder dekrementieren und um zurückkonvertieren Double.longBitsToDouble()
;Dadurch erhalten Sie die nächste oder vorherige Darstellung double
Wert -- in den meisten Fällen:Es gibt ein paar Sonderfälle (NaN, unendliche Werte), daher ist dies für Gleitkomma-Neulinge nicht zu empfehlen :)
Andere Tipps
doppelt hat eine begrenzte Präzision.Min_Normal ist 2e-1022.Es wird heruntergefallen, es sei denn, die Nummer, die Sie hinzufügen, ist auch im Kugelschreiber von 2E-1000.