Por que Double.MIN_VALUE não é negativo

157

Alguém pode esclarecer porque Double.MIN_VALUEnão é realmente o valor mínimo que o Doubles pode receber? É um valor positivo, e um Double pode, é claro, ser negativo.

Entendo por que é um número útil, mas parece um nome pouco intuitivo, especialmente quando comparado a Integer.MIN_VALUE . Ligá-lo Double.SMALLEST_POSITIVEou MIN_INCREMENTsimilar teria uma semântica mais clara.

Além disso, qual é o valor mínimo que o Doubles pode receber? É isso -Double.MAX_VALUE? Os documentos não parecem dizer.

mo-seph
fonte
1
Obrigado pelas respostas! A diferença entre alcance e precisão faz sentido. Ainda acho a nomeação bastante estranha e inconsistente, mas é viável.
mo-seph
1
Eu acho que é porque foi escrito pelos mesmos gênios que chamaram um método writeBytesque usa a String.
Trejkaz
Basicamente, você está certo, é uma semântica ruim #
Alvaro

Respostas:

180

O formato IEEE 754 tem um bit reservado para o sinal e os bits restantes representando a magnitude. Isso significa que é "simétrico" ao redor do origo (em oposição aos valores Inteiros, que têm mais um valor negativo). Portanto, o valor mínimo é simplesmente o mesmo que o valor máximo, com o bit de sinal alterado, portanto , sim , -Double.MAX_VALUEé o menor número real possível que você pode representar com a double.

Suponho que isso Double.MAX_VALUEdeva ser visto como magnitude máxima ; nesse caso, faz sentido simplesmente escrever -Double.MAX_VALUE. Também explica por que Double.MIN_VALUEé o valor menos positivo (já que isso representa a menor magnitude possível).

Mas claro, concordo que o nome é um pouco enganador. Ao me acostumar com o significado Integer.MIN_VALUE, também fiquei um pouco surpreso ao ler que esse Double.MIN_VALUEera o menor valor absoluto que poderia ser representado. Talvez eles achem supérfluo ter uma constante que represente o menor valor possível, pois é simplesmente uma -distânciaMAX_VALUE :-)

(Observe, também há, Double.NEGATIVE_INFINITYmas estou desconsiderando isso, pois ele deve ser visto como um "caso especial" e, de fato, não representa nenhum número real.)

Aqui está um bom texto sobre o assunto.

aioobe
fonte
3
Obrigado por isso. Eu estava portando algum código de análise estatística e traduzindo cegamente java para C #. Notei alguns números saindo em -infinity ou NaN e dei uma olhada no algoritmo. Percebi que double.MIN_VALUE não fazia sentido no contexto e fiz uma pesquisa. Esta publicação aparece antes dos documentos java. É realmente um nome confuso para o que realmente é double.Epsilon. Não é grande coisa, levou menos de um minuto para consertar, mas definitivamente surpreendente.
Ed S.
O "menor valor absoluto que pode ser representado" não deveria ser chamado de "epsilon"?
Dave Cousineau 28/08
@Ahuagin, não é realmente "suposto" ter o nome de algo em particular. Epsilon é apenas uma letra grega que geralmente representa uma quantidade positiva arbitrariamente pequena em matemática / física. Vá escolheuSmallestNonzeroFloat64 por exemplo.
aioobe
12

Essas constantes não têm nada a ver com sinal. Isso faz mais sentido se você considerar um duplo como um composto de três partes: Sign, Exponent e Mantissa. Double.MIN_VALUE é, na verdade, o menor valor que Mantissa pode assumir quando o expoente estiver no valor mínimo antes que ocorra uma descarga para zero. Da mesma forma, MAX_VALUE pode ser entendido como o maior valor que Mantissa pode assumir quando o expoente estiver no valor máximo antes que ocorra uma liberação para o infinito.

Um nome mais descritivo para esses dois poderia ser Maior Absoluto (adicione diferente de zero para verbosidade) e Menor Menor Absoluto Valor (adicione não-infinito para verbosidade).

Confira o padrão IEEE 754 (1985) para obter detalhes. Existe uma versão revisada (2008), mas que apenas introduz mais formatos que nem são suportados pelo java (estritamente falando, o java ainda não suporta alguns recursos obrigatórios do IEEE 754 1985, como muitos outros idiomas de alto nível).

Durandal
fonte
4

Presumo que os nomes confusos possam ser rastreados até C , que definiuFLT_MIN como o menor número positivo.

Como em Java, onde você tem que usar -Double.MAX_VALUE, você precisa usar -FLT_MAXpara obter o menor número flutuante em C.

Philipp Claßen
fonte
3

O valor mínimo para um duplo é por Double.NEGATIVE_INFINITYisso que Double.MIN_VALUEnão é realmente o mínimo para a Double.

Como os números duplos são de ponto flutuante, você pode ter apenas o maior número (com menor precisão) ou o número mais próximo a 0 (com grande precisão).

Se você realmente deseja um valor mínimo para um dobro que não é infinito, pode usar -Double.MAX_VALUE.

Colin Hebert
fonte
1
Seguindo essa ideia, o valor máximo para um Double Double.MAX_VALUE ou Double.POSITIVE_INFINITY?
mo-seph
Double.MIN_VALUEpoderia ser igual a Double.NEGATIVE_INFINITY.
Starblue #
@starblue, não. @ mo-seph,, Double.POSITIVE_INFINITY+ ∞> tudo e —∞ <tudo #
Colin Hebert
@Colin Hebert,> = e <= para ser mais preciso ;-)
aioobe
Você provavelmente me entendeu mal. Em um mundo melhor, Double.MIN_VALUEseria igual a Double.NEGATIVE_INFINITY, porque seria consistente com MIN_VALUEos tipos inteiros. Eu poderia inicializar qualquer variável para calcular o máximo com MIN_VALUEe seria correto. O Double.MIN_VALUEque temos agora teria um nome melhor. (E analogamente para MAX_VALUE.)
Starblue
2

Porque com números de ponto flutuante, a precisão é o que é importante, pois não há alcance exato .

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

Mas concordo que provavelmente deveria ter sido nomeado algo melhor :)

John Gardner
fonte
OK, mas por que faz sentido ter Double.MAX_VALUE? Isso parece estar claramente definido.
mo-seph
porque é o valor máximo preciso (não infinito), não contabilizando seu sinal.
John Gardner
0

Como diz nos documentos ,

Double.MIN_VALUE é uma constante que mantém o menor valor POSITIVO diferente de zero do tipo double, 2 ^ (- 1074).

O truque aqui é que estamos falando de uma representação de número de ponto flutuante. O tipo de dados duplo é um ponto flutuante IEEE 754 de 64 bits e precisão dupla. Os pontos flutuantes representam números de 1.000.000.000.000 a 0.0000000000000001 com facilidade e maximizando a precisão (o número de dígitos) nas duas extremidades da escala. (Para saber mais, consulte este )

A mantissa, sempre um número positivo , contém os dígitos significativos do número de ponto flutuante. O expoente indica a potência positiva ou negativa da raiz pela qual a mantissa e o sinal devem ser multiplicados. Os quatro componentes são combinados da seguinte maneira para obter o valor do ponto flutuante.

insira a descrição da imagem aqui

Pense que MIN_VALUE é o valor mínimo que a mantissa pode representar. Como os valores mínimos de uma representação de ponto flutuante é a magnitude mínima que pode ser representada usando isso. (Poderia ter usado um nome melhor para evitar essa confusão)

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


Abaixo está apenas o FYI.

O ponto flutuante de precisão dupla pode representar 2.098 potências de dois, de 2 ^ -1074 a 2 ^ 1023. Os poderes desnormalizados de dois são os de 2 ^ -1074 a 2 ^ -1023; potências normalizadas de dois são aquelas de 2 ^ -1022 a 2 ^ 1023. Consulte isto e isto .

prime
fonte
Obrigado! Não sei por que essa resposta foi reduzida.
Combine