Warum ist Double.MIN_VALUE nicht negativ?

157

Kann jemand etwas Licht ins Dunkel bringen, warum Double.MIN_VALUEnicht der Mindestwert ist, den Doppel annehmen können? Es ist ein positiver Wert, und ein Double kann natürlich negativ sein.

Ich verstehe, warum es eine nützliche Zahl ist, aber es scheint ein sehr unintuitiver Name zu sein, besonders im Vergleich zu Integer.MIN_VALUE. Nennt es Double.SMALLEST_POSITIVEoder MIN_INCREMENTwürde oder ähnliche klarere Semantik hat.

Was ist der Mindestwert, den Doubles annehmen können? Ist es -Double.MAX_VALUE? Die Dokumente scheinen nicht zu sagen.

mo-seph
quelle
1
Danke für die Antworten! Der Unterschied zwischen Reichweite und Präzision ist sinnvoll. Ich finde die Benennung immer noch ziemlich seltsam und inkonsistent, aber es ist praktikabel.
Mo-Seph
1
Ich vermute, weil es von denselben Genies geschrieben wurde, die eine Methode genannt haben, writeBytesdie a nimmt String.
Trejkaz
Grundsätzlich haben Sie Recht, es ist schlechte Semantik
Alvaro

Antworten:

180

Das IEEE 754-Format hat ein Bit, das für das Vorzeichen reserviert ist, und die verbleibenden Bits, die die Größe darstellen. Dies bedeutet, dass es um origo "symmetrisch" ist (im Gegensatz zu den Integer-Werten, die einen weiteren negativen Wert haben). Somit ist der Minimalwert einfach der gleiche wie der Maximalwert, wobei das Vorzeichenbit geändert wird. Ja , dies -Double.MAX_VALUEist die kleinstmögliche tatsächliche Zahl, die Sie mit a darstellen können double.

Ich nehme an, das Double.MAX_VALUEsollte als maximale Größe angesehen werden. In diesem Fall ist es tatsächlich sinnvoll, einfach zu schreiben -Double.MAX_VALUE. Es wird auch erklärt, warum Double.MIN_VALUEder Wert am wenigsten positiv ist (da dies die geringstmögliche Größe darstellt).

Aber sicher stimme ich zu, dass die Benennung etwas irreführend ist. Da Integer.MIN_VALUEich an die Bedeutung gewöhnt war, war auch ich etwas überrascht, als ich las, dass dies Double.MIN_VALUEder kleinste absolute Wert war, der dargestellt werden konnte. Vielleicht hielten sie es für überflüssig, eine Konstante zu haben, die den geringstmöglichen Wert darstellt, da sie einfach nicht zu -erreichen ist MAX_VALUE:-)

(Beachten Sie, dass es auch gibt, Double.NEGATIVE_INFINITYaber ich ignoriere dies, da es als "Sonderfall" anzusehen ist und tatsächlich keine tatsächliche Zahl darstellt.)

Hier ist ein guter Text zu diesem Thema.

aioobe
quelle
3
Danke dafür. Ich habe statistischen Analysecode portiert und Java blind in C # übersetzt. Ich bemerkte einige Zahlen, die bei -infinity oder NaN herauskamen, und sah mir den Algorithmus genauer an. Ich erkannte, dass double.MIN_VALUE im Kontext keinen Sinn ergab und führte eine Suche durch. Dieser Beitrag erscheint vor den Java-Dokumenten. Es ist wirklich ein verwirrender Name für das, was wirklich doppelt ist. Keine große Sache, die Reparatur dauerte weniger als eine Minute, aber definitiv überraschend.
Ed S.
Soll der "kleinste absolute Wert, der dargestellt werden kann" nicht "epsilon" heißen?
Dave Cousineau
@Sahuagin, es ist nicht wirklich "angeblich", etwas Bestimmtes zu nennen. Epsilon ist nur ein griechischer Buchstabe, der üblicherweise eine beliebig kleine positive Größe in Mathematik / Physik darstellt. Gehen Sie SmallestNonzeroFloat64zum Beispiel gewählt.
Aioobe
12

Diese Konstanten haben nichts mit Vorzeichen zu tun. Dies ist sinnvoller, wenn Sie ein Double als eine Zusammensetzung aus drei Teilen betrachten: Zeichen, Exponent und Mantisse. Double.MIN_VALUE ist tatsächlich der kleinste Wert, den Mantissa annehmen kann, wenn sich der Exponent auf einem minimalen Wert befindet, bevor ein Flush auf Null auftritt. Ebenso kann MAX_VALUE als der größte Wert verstanden werden, den Mantissa annehmen kann, wenn der Exponent den Maximalwert erreicht, bevor ein Flush ins Unendliche auftritt.

Ein aussagekräftigerer Name für diese beiden könnte " Größtes Absolut" (Add-Nicht-Null für Verbositiy) und Kleinster Absolut- Wert (Add Nicht-Unendlich für Verbositiy) sein.

Weitere Informationen finden Sie im IEEE 754 (1985) -Standard. Es gibt eine überarbeitete Version (2008), die jedoch nur weitere Formate einführt, die nicht einmal von Java unterstützt werden (genau genommen unterstützt Java einige obligatorische Funktionen von IEEE 754 1985 nicht, wie viele andere Hochsprachen).

Durandal
quelle
4

Ich gehe davon aus, dass die verwirrenden Namen auf C zurückgeführt werden können , das FLT_MINals kleinste positive Zahl definiert ist.

Wie in Java, wo Sie verwenden müssen -Double.MAX_VALUE, müssen Sie verwenden -FLT_MAX, um den kleinsten Float in C zu erhalten.

Philipp Claßen
quelle
3

Der Mindestwert für ein Double ist Double.NEGATIVE_INFINITY, weshalb dies Double.MIN_VALUEnicht wirklich der Mindestwert für ein Double ist Double.

Da es sich bei dem Doppel um Gleitkommazahlen handelt, können Sie nur die größte Zahl (mit geringerer Genauigkeit) oder die Nummer 0 (mit hoher Genauigkeit) am nächsten kommen.

Wenn Sie wirklich einen minimalen Wert für ein Double wollen, das nicht unendlich ist, können Sie verwenden -Double.MAX_VALUE.

Colin Hebert
quelle
1
Ist nach dieser Idee der Maximalwert für Double Double.MAX_VALUE oder Double.POSITIVE_INFINITY?
Mo-Seph
Double.MIN_VALUEkönnte gleich sein Double.NEGATIVE_INFINITY.
Starblue
@starblue, nein. @ mo-seph ,, Double.POSITIVE_INFINITY+ ∞> alles und
Colin Hebert
@Colin Hebert,> = und <= um genau zu sein
;-)
Sie haben mich wahrscheinlich falsch verstanden. In einer besseren Welt Double.MIN_VALUEwäre das gleich Double.NEGATIVE_INFINITY, denn dann wäre es konsistent mit MIN_VALUEden Integer-Typen. Ich könnte jede Variable für die Berechnung eines Maximums mit initialisieren MIN_VALUEund es wäre korrekt. Das haben Double.MIN_VALUEwir jetzt hätten einen besseren Namen. (Und analog für MAX_VALUE.)
Starblue
2

Denn bei Gleitkommazahlen ist die Genauigkeit wichtig, da es keinen genauen Bereich gibt .

/**
 * A constant holding the smallest positive nonzero value of type
 * <code>double</code>, 2<sup>-1074</sup>. It is equal to the
 * hexadecimal floating-point literal
 * <code>0x0.0000000000001P-1022</code> and also equal to
 * <code>Double.longBitsToDouble(0x1L)</code>.
 */

Aber ich stimme zu, dass es wahrscheinlich etwas besseres hätte heißen sollen :)

John Gardner
quelle
OK, aber warum ist es dann sinnvoll, Double.MAX_VALUE zu haben? Das scheint klar definiert zu sein.
Mo-Seph
weil es der maximale genaue Wert ist (nicht unendlich), ohne sein Vorzeichen zu berücksichtigen.
John Gardner
0

Wie es in den Dokumenten heißt ,

Double.MIN_VALUE ist eine Konstante, die den kleinsten POSITIVEN Wert ungleich Null vom Typ double, 2 ^ (- 1074), enthält.

Der Trick hier ist, dass es sich um eine Gleitkommazahlendarstellung handelt. Der doppelte Datentyp ist ein 64-Bit-IEEE 754-Gleitkomma mit doppelter Genauigkeit. Gleitkommazahlen repräsentieren mühelos Zahlen von 1.000.000.000.000 bis 0,0000000000000001 und maximieren gleichzeitig die Genauigkeit (die Anzahl der Stellen) an beiden Enden der Skala. (Weitere Informationen finden Sie hier )

Die Mantisse, immer eine positive Zahl , enthält die signifikanten Ziffern der Gleitkommazahl. Der Exponent gibt die positive oder negative Potenz des Radix an, mit der Mantisse und Vorzeichen multipliziert werden sollen. Die vier Komponenten werden wie folgt kombiniert , um den Gleitkommawert zu erhalten.

Geben Sie hier die Bildbeschreibung ein

Denken Sie, dass MIN_VALUE der Mindestwert ist, den die Mantisse darstellen kann. Als Mindestwerte einer Gleitkommadarstellung gilt die Mindestgröße, die damit dargestellt werden kann. (Hätte einen besseren Namen verwenden können, um diese Verwirrung zu vermeiden)

123> 10> 1> 0,12> 0,012> 0,0000123> 0,000000001> 0,0000000000000001


Unten ist nur zu Ihrer Information.

Gleitkommazahlen mit doppelter Genauigkeit können 2.098 Zweierpotenzen von 2 ^ -1074 bis 2 ^ 1023 darstellen. Denormalisierte Zweierpotenzen sind die von 2 ^ -1074 bis 2 ^ -1023; normalisierte Zweierpotenzen sind die von 2 ^ -1022 bis 2 ^ 1023. Verweisen Sie dies und das .

Prime
quelle
Danke dir! Ich weiß nicht, warum diese Antwort abgelehnt wurde.
Kombinieren Sie den