¿Por qué Double.MIN_VALUE no es negativo?

157

¿Alguien puede arrojar algo de luz sobre por qué Double.MIN_VALUEno es realmente el valor mínimo que los Dobles pueden tomar? Es un valor positivo, y un Doble puede, por supuesto, ser negativo.

Entiendo por qué es un número útil, pero parece un nombre muy poco intuitivo, especialmente en comparación con Integer.MIN_VALUE. Llamándolo Double.SMALLEST_POSITIVEo MIN_INCREMENTo semejante tendría la semántica más claras.

Además, ¿cuál es el valor mínimo que pueden tomar los Dobles? Es -Double.MAX_VALUE? Los documentos no parecen decir.

mo-seph
fuente
1
Gracias por las respuestas! La diferencia entre rango y precisión tiene sentido. Todavía encuentro el nombre bastante extraño e inconsistente, pero es viable.
mo-seph
1
Supongo que está escrito por los mismos genios que llamaron a un método writeBytesque toma a String.
Trejkaz
Básicamente, tienes razón, es mala semántica
Alvaro

Respuestas:

180

El formato IEEE 754 tiene un bit reservado para el signo y los bits restantes que representan la magnitud. Esto significa que es "simétrico" alrededor del origo (en oposición a los valores enteros, que tienen un valor negativo más). Por lo tanto, el valor mínimo es simplemente el mismo que el valor máximo, con el bit de signo cambiado, así que , -Double.MAX_VALUEes el número real más pequeño posible que puede representar con a double.

Supongo que Double.MAX_VALUEdebería verse como la máxima magnitud , en cuyo caso en realidad tiene sentido simplemente escribir -Double.MAX_VALUE. También explica por qué Double.MIN_VALUEes el valor menos positivo (ya que representa la menor magnitud posible).

Pero claro, estoy de acuerdo en que nombrar es un poco engañoso. Al estar acostumbrado al significado Integer.MIN_VALUE, también me sorprendió un poco cuando leí que ese Double.MIN_VALUEera el valor absoluto más pequeño que podía representarse. Tal vez pensaron que era superfluo tener una constante que representara el menor valor posible, ya que simplemente está -lejos de MAX_VALUE:-)

(Tenga en cuenta que también existe, Double.NEGATIVE_INFINITYpero no tengo en cuenta esto, ya que debe considerarse como un "caso especial" y, de hecho, no representa ningún número real).

Aquí hay un buen texto sobre el tema.

aioobe
fuente
3
Gracias por esto. Estaba portando un código de análisis estadístico y traduciendo ciegamente Java a C #. Noté que algunos números salían al infinito o NaN y eché un vistazo más de cerca al algoritmo. Me di cuenta de que double.MIN_VALUE no tenía sentido en contexto e hice una búsqueda. Esta publicación aparece antes de los documentos de Java. Realmente es un nombre confuso para lo que realmente es doble: Epilon. No es gran cosa, tardó menos de un minuto en arreglarlo, pero definitivamente es sorprendente.
Ed S.
¿No se supone que el "valor absoluto más pequeño que se puede representar" se llama 'epsilon'?
Dave Cousineau
@Sahuagin, en realidad no se "supone" que se llame algo en particular. Epsilon es solo una letra griega que comúnmente representa una cantidad positiva arbitrariamente pequeña en matemáticas / física. Ir elegido SmallestNonzeroFloat64por ejemplo.
aioobe
12

Estas constantes no tienen nada que ver con el signo. Esto tiene más sentido si considera un doble como un compuesto de tres partes: signo, exponente y mantisa. Double.MIN_VALUE es en realidad el valor más pequeño que Mantissa puede asumir cuando el exponente está en el valor mínimo antes de que ocurra un vaciado a cero. Del mismo modo, MAX_VALUE puede entenderse como el valor más grande que Mantissa puede asumir cuando el exponente está en el valor máximo antes de que ocurra una descarga al infinito.

Un nombre más descriptivo para estos dos podría ser Absoluto más grande (agregue distinto de cero para verbositiy) y Absoluto más pequeño valor (agregar no infinito para verbositiy).

Consulte el estándar IEEE 754 (1985) para más detalles. Hay una versión revisada (2008), pero que solo introduce más formatos que ni siquiera son compatibles con java (estrictamente hablando, java incluso carece de soporte para algunas características obligatorias de IEEE 754 1985, como muchos otros lenguajes de alto nivel).

Durandal
fuente
4

Supongo que los nombres confusos se remontan a C , que definióFLT_MIN como el número positivo más pequeño.

Al igual que en Java, donde tiene que usar -Double.MAX_VALUE, debe usar -FLT_MAXpara obtener el flotador más pequeño en C.

Philipp Claßen
fuente
3

El valor mínimo para un doble es Double.NEGATIVE_INFINITYpor eso Double.MIN_VALUEque no es realmente el mínimo para unDouble .

Como el doble son números de coma flotante, solo puede tener el número más grande (con una precisión más baja) o el número más cercano a 0 (con una gran precisión).

Si realmente desea un valor mínimo para un doble que no sea infinito, puede usarlo -Double.MAX_VALUE.

Colin Hebert
fuente
1
Siguiendo esa idea, ¿es el valor máximo para Double Double.MAX_VALUE o Double.POSITIVE_INFINITY?
mes de septiembre
Double.MIN_VALUEpodría ser igual a Double.NEGATIVE_INFINITY.
Starblue
@starblue, no. @ mo-seph,, Double.POSITIVE_INFINITY+ ∞> todo y —∞ <todo
Colin Hebert
@Colin Hebert,> = y <= para ser precisos ;-)
aioobe
Probablemente me malinterpretaste. En un mundo mejor, Double.MIN_VALUEsería igual a Double.NEGATIVE_INFINITY, porque entonces sería coherente con MIN_VALUElos tipos enteros. Podría inicializar cualquier variable para calcular un máximo con MIN_VALUEy sería correcto. El Double.MIN_VALUEque tenemos ahora tendría un mejor nombre. (Y análogamente para MAX_VALUE.)
starblue
2

Porque con los números de coma flotante, la precisión es lo importante, ya que no hay un rango exacto .

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

Pero estoy de acuerdo en que probablemente debería haber sido nombrado algo mejor :)

John Gardner
fuente
Bien, pero ¿por qué tiene sentido tener Double.MAX_VALUE? Eso parece estar claramente definido.
mo-seph
porque es el valor máximo preciso (no infinito), sin tener en cuenta su signo.
John Gardner
0

Como dice en los documentos ,

Double.MIN_VALUE es una constante que contiene el menor valor POSITIVO distinto de cero del tipo double, 2 ^ (- 1074).

El truco aquí es que estamos hablando de una representación de número de coma flotante. El tipo de datos doble es un punto flotante IEEE 754 de doble precisión de 64 bits. Los puntos flotantes representan números de 1,000,000,000,000 a 0.0000000000000001 con facilidad y maximizan la precisión (el número de dígitos) en ambos extremos de la escala. (Para más consulte esto )

La mantisa, siempre un número positivo , contiene los dígitos significativos del número de coma flotante. El exponente indica la potencia positiva o negativa de la raíz por la cual la mantisa y el signo deben multiplicarse. Los cuatro componentes se combinan de la siguiente manera para obtener el valor de coma flotante.

ingrese la descripción de la imagen aquí

Piense que MIN_VALUE es el valor mínimo que la mantisa puede representar. Como los valores mínimos de una representación en coma flotante es la magnitud mínima que se puede representar con eso. (Sin embargo, podría haber usado un nombre mejor para evitar esta confusión)

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


A continuación se muestra solo para su información.

La coma flotante de doble precisión puede representar 2.098 potencias de dos, desde 2 ^ -1074 hasta 2 ^ 1023. Los poderes desnormalizados de dos son aquellos desde 2 ^ -1074 hasta 2 ^ -1023; las potencias normalizadas de dos son aquellas desde 2 ^ -1022 hasta 2 ^ 1023. Consulte esto y esto .

principal
fuente
¡Gracias! No sé por qué esta respuesta fue rechazada.
Combinar