Perché Double.MIN_VALUE non è negativo


157

Qualcuno può far luce su perché in Double.MIN_VALUErealtà non è il valore minimo che può assumere Double? È un valore positivo e un doppio può ovviamente essere negativo.

Capisco perché è un numero utile, ma sembra un nome molto poco intuitivo, soprattutto se confrontato con Integer.MIN_VALUE. Chiamarlo Double.SMALLEST_POSITIVEo MIN_INCREMENTo simile avrebbe avuto una semantica più chiare.

Inoltre, qual è il valore minimo che può assumere Double? È vero -Double.MAX_VALUE? I documenti non sembrano dire.


1
Grazie per le risposte! La differenza tra gamma e precisione ha senso. Trovo ancora la denominazione abbastanza strana e incoerente, ma è praticabile.
lunedì

1
Immagino perché è scritto dagli stessi geni che hanno chiamato un metodo writeBytesche richiede un String.
Trejkaz,

Fondamentalmente, hai ragione, è una cattiva semantica
Alvaro il

Risposte:


180

Il formato IEEE 754 ha un bit riservato per il segno e i bit rimanenti che rappresentano la grandezza. Ciò significa che è "simmetrico" attorno all'origo (al contrario dei valori Integer, che hanno un altro valore negativo). Pertanto, il valore minimo è semplicemente uguale al valore massimo, con il bit di segno modificato, quindi , -Double.MAX_VALUEè il numero effettivo più piccolo possibile che è possibile rappresentare con undouble .

Suppongo che Double.MAX_VALUEdovrebbe essere visto come massima grandezza , nel qual caso ha davvero senso semplicemente scrivere -Double.MAX_VALUE. Spiega anche perché Double.MIN_VALUEè il valore meno positivo (poiché rappresenta la grandezza minima possibile).

Ma certo, sono d'accordo sul fatto che la denominazione sia un po 'fuorviante. Essendo abituato al significato Integer.MIN_VALUE, anch'io sono rimasto un po 'sorpreso quando ho letto che Double.MIN_VALUEera il più piccolo valore assoluto che potesse essere rappresentato. Forse hanno pensato che fosse superfluo avere una costante che rappresentasse il minor valore possibile in quanto è semplicemente una -distanza da MAX_VALUE:-)

(Nota, c'è anche, Double.NEGATIVE_INFINITYma non mi sto ignorando, poiché deve essere visto come un "caso speciale" e in realtà non rappresenta alcun numero reale.)

Ecco un buon testo sull'argomento.


3
Grazie per questo. Stavo eseguendo il porting di un codice di analisi statistica e traducendo ciecamente java in C #. Ho notato alcuni numeri uscire a -infinity o NaN e ho dato un'occhiata più da vicino all'algoritmo. Mi sono reso conto che double.MIN_VALUE non aveva senso nel contesto e ho fatto una ricerca. Questo post arriva prima dei documenti di Java. È davvero un nome confuso per ciò che è davvero double.Epsilon. Non è un grosso problema, ci è voluto meno di un minuto per risolvere, ma sicuramente sorprendente.
Ed S.

Il "più piccolo valore assoluto che può essere rappresentato" non dovrebbe essere chiamato "epsilon"?
Dave Cousineau,

@Sahuagin, non è proprio "supposto" di essere nominato in modo particolare. Epsilon è solo una lettera greca che rappresenta comunemente una quantità arbitrariamente piccola in matematica / fisica. Vai scelto SmallestNonzeroFloat64per esempio.
aioobe,

12

Queste costanti non hanno nulla a che fare con il segno. Ciò ha più senso se si considera un doppio come un composto di tre parti: Segno, Esponente e Mantissa. Double.MIN_VALUE è in realtà il valore più piccolo che Mantissa può assumere quando l'esponente è al valore minimo prima che si verifichi un flush a zero. Allo stesso modo MAX_VALUE può essere inteso come il valore più grande che Mantissa può assumere quando l'esponente è al valore massimo prima che si verifichi un flush all'infinito.

Un nome più descrittivo per questi due potrebbe essere Assoluto più grande (aggiungi non zero per verbositiy) e Valore assoluto più piccolo (aggiungi non-infinito per verbositiy).

Per i dettagli, consulta lo standard IEEE 754 (1985) . Esiste una versione rivista (2008), ma che introduce solo più formati che non sono nemmeno supportati da Java (a rigor di termini Java manca anche il supporto per alcune funzionalità obbligatorie di IEEE 754 1985, come molte altre lingue di alto livello).



3

Il valore minimo per un doppio è Double.NEGATIVE_INFINITYper questo che Double.MIN_VALUEnon è proprio il minimo per a Double.

Dato che i doppi sono numeri in virgola mobile, puoi avere solo il numero più grande (con una precisione inferiore) o il numero più vicino a 0 (con una grande precisione).

Se vuoi davvero un valore minimo per un doppio che non sia infinito, puoi usarlo -Double.MAX_VALUE.


1
A seguito di tale idea, è il valore massimo per Double Double.MAX_VALUE o Double.POSITIVE_INFINITY?
lun-seph,

Double.MIN_VALUEpotrebbe essere uguale a Double.NEGATIVE_INFINITY.
Starblue,

@starblue, no. @ mo-seph,, Double.POSITIVE_INFINITY+ ∞> tutto e —∞ <tutto
Colin Hebert

@Colin Hebert,> = e <= per essere precisi ;-)
aioobe,

Probabilmente mi hai frainteso. In un mondo migliore, Double.MIN_VALUEsarebbe uguale a Double.NEGATIVE_INFINITY, perché sarebbe coerente con MIN_VALUEi tipi interi. Potrei inizializzare qualsiasi variabile per calcolare un massimo con MIN_VALUEe sarebbe corretto. L' Double.MIN_VALUEabbiamo ora avrebbe un nome migliore. (E analogamente per MAX_VALUE.)
Starblue,

2

Perché con numeri in virgola mobile, la precisione è ciò che è importante in quanto non esiste un intervallo esatto .

/**
 * 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>.
 */

Ma concordo sul fatto che probabilmente avrebbe dovuto essere chiamato con un nome migliore :)


OK, ma allora perché ha senso avere Double.MAX_VALUE? Sembra che sia chiaramente definito.
lun-seph,

perché è il massimo valore preciso (non infinito), non tenendo conto del suo segno.
John Gardner,

0

Come dice nei documenti ,

Double.MIN_VALUE è una costante che detiene il valore POSITIVO più piccolo diverso da zero di tipo double, 2 ^ (- 1074).

Il trucco qui è che stiamo parlando di una rappresentazione numerica in virgola mobile. Il doppio tipo di dati è un IEEE 754 a virgola mobile a 64 bit a doppia precisione. I punti fluttuanti rappresentano i numeri da 1.000.000.000.000 a 0.0000000000000001 con facilità e massimizzando la precisione (il numero di cifre) su entrambe le estremità della scala. (Per ulteriori informazioni consultare questo )

La mantissa, sempre un numero positivo , contiene le cifre significative del numero in virgola mobile. L'esponente indica il potere positivo o negativo della radice per cui la mantissa e il segno dovrebbero essere moltiplicati per. I quattro componenti sono combinati come segue per ottenere il valore in virgola mobile.

inserisci qui la descrizione dell'immagine

Pensa che MIN_VALUE è il valore minimo che la mantissa può rappresentare. Poiché i valori minimi di una rappresentazione in virgola mobile è la magnitudine minima che può essere rappresentata usando quello. (Avrebbe potuto usare un nome migliore per evitare questa confusione)

123> 10> 1> 0.12> 0.012> 0.0000123> 0.000000001> 0.0000000000000001


Di seguito è solo FYI.

Il virgola mobile a precisione doppia può rappresentare 2.098 potenze di due, da 2 ^ -1074 a 2 ^ 1023. I poteri denormalizzati di due sono quelli da 2 ^ -1074 a 2 ^ -1023; i poteri normalizzati di due sono quelli da 2 ^ -1022 a 2 ^ 1023. Fare riferimento a questo e questo .


Grazie! Non so perché questa risposta sia stata sottoposta a downgrade.
Combina il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.