Pourquoi Double.MIN_VALUE n'est pas négatif

157

Quelqu'un peut-il expliquer pourquoi ce Double.MIN_VALUEn'est pas la valeur minimale que les doubles peuvent prendre? C'est une valeur positive, et un Double peut bien sûr être négatif.

Je comprends pourquoi c'est un nombre utile, mais cela semble un nom très peu intuitif, surtout par rapport à Integer.MIN_VALUE. L'appeler Double.SMALLEST_POSITIVEou MIN_INCREMENTou similaire aurait une sémantique plus claire.

De plus, quelle est la valeur minimale que les doubles peuvent prendre? C'est ça -Double.MAX_VALUE? Les documents ne semblent pas le dire.

mo-seph
la source
1
Merci pour les réponses! La différence entre la portée et la précision est logique. Je trouve toujours la dénomination assez étrange et incohérente, mais c'est réalisable.
mo-seph
1
Je suppose parce que c'est écrit par les mêmes génies qui ont appelé une méthode writeBytesqui prend un String.
Trejkaz
En gros, vous avez raison, c'est une mauvaise sémantique
Alvaro

Réponses:

180

Le format IEEE 754 a un bit réservé pour le signe et les bits restants représentant la grandeur. Cela signifie qu'il est "symétrique" autour de l'origo (par opposition aux valeurs Integer, qui ont encore une valeur négative). Ainsi, la valeur minimale est simplement la même que la valeur maximale, avec le bit de signe modifié, donc oui , -Double.MAX_VALUEc'est le plus petit nombre réel possible que vous pouvez représenter avec a double.

Je suppose que le Double.MAX_VALUEdevrait être considéré comme une magnitude maximale , auquel cas il est en fait logique d'écrire simplement -Double.MAX_VALUE. Cela explique également pourquoi Double.MIN_VALUEest la valeur la moins positive (puisque cela représente la moindre ampleur possible).

Mais bien sûr, je conviens que la dénomination est un peu trompeuse. Étant habitué à la signification Integer.MIN_VALUE, j'ai moi aussi été un peu surpris quand j'ai lu que Double.MIN_VALUEc'était la plus petite valeur absolue qui pouvait être représentée. Peut-être ont-ils pensé qu'il était superflu d'avoir une constante représentant la moindre valeur possible car elle est simplement -éloignée de MAX_VALUE:-)

(Remarque, il y en a aussi Double.NEGATIVE_INFINITYmais je ne tiens pas compte de cela, car il doit être considéré comme un "cas spécial" et ne représente en fait aucun nombre réel.)

Voici un bon texte sur le sujet.

aioobe
la source
3
Merci pour cela. Je portais du code d'analyse statistique et je traduisais aveuglément Java en C #. J'ai remarqué des nombres sortant à -infinity ou NaN et j'ai examiné de plus près l'algorithme. J'ai réalisé que double.MIN_VALUE n'avait aucun sens dans le contexte et j'ai fait une recherche. Ce message apparaît avant la documentation java. C'est vraiment un nom déroutant pour ce qui est vraiment double.Epsilon. Ce n'est pas grave, a pris moins d'une minute à réparer, mais vraiment surprenant.
Ed S.
La "plus petite valeur absolue pouvant être représentée" n'est-elle pas censée s'appeler "epsilon"?
Dave Cousineau
@Sahuagin, ce n'est pas vraiment "censé" être nommé quelque chose de particulier. Epsilon est juste une lettre grecque qui représente généralement une quantité positive arbitrairement petite en mathématiques / physique. Allez a choisi SmallestNonzeroFloat64par exemple.
aioobe
12

Ces constantes n'ont rien à voir avec le signe. Cela a plus de sens si vous considérez un double comme un composite de trois parties: signe, exposant et mantisse. Double.MIN_VALUE est en fait la plus petite valeur que Mantissa peut prendre lorsque l'exposant est à la valeur minimale avant qu'un vidage à zéro ne se produise. De même, MAX_VALUE peut être compris comme la plus grande valeur que Mantissa peut prendre lorsque l'exposant est à sa valeur maximale avant qu'un vidage à l'infini ne se produise.

Un nom plus descriptif pour ces deux pourrait être le plus grand absolu (ajouter une valeur non nulle pour la verbosité) et la plus petite valeur absolue (ajouter une valeur non infinie pour la verbosité).

Consultez la norme IEEE 754 (1985) pour plus de détails. Il existe une version révisée (2008), mais qui n'introduit que plus de formats qui ne sont même pas pris en charge par java (java à proprement parler ne prend même pas en charge certaines fonctionnalités obligatoires de IEEE 754 1985, comme beaucoup d'autres langages de haut niveau).

Durandal
la source
4

Je suppose que les noms confus peuvent être attribués à C , qui est défini FLT_MINcomme le plus petit nombre positif.

Comme en Java, où vous devez utiliser -Double.MAX_VALUE, vous devez utiliser -FLT_MAXpour obtenir le plus petit flotteur en C.

Philipp Claßen
la source
3

La valeur minimale pour un double, Double.NEGATIVE_INFINITYc'est pourquoi ce Double.MIN_VALUEn'est pas vraiment le minimum pour un Double.

Comme les doubles sont des nombres à virgule flottante, vous ne pouvez avoir que le plus grand nombre (avec une précision inférieure) ou le nombre le plus proche de 0 (avec une grande précision).

Si vous voulez vraiment une valeur minimale pour un double qui n'est pas l'infini, vous pouvez utiliser -Double.MAX_VALUE.

Colin Hebert
la source
1
Suite à cette idée, est la valeur maximale pour un Double Double.MAX_VALUE ou Double.POSITIVE_INFINITY?
mo-seph
Double.MIN_VALUEpourrait être égal à Double.NEGATIVE_INFINITY.
starblue
@starblue, non. @ mo-seph,, Double.POSITIVE_INFINITY+ ∞> tout et —∞ <tout
Colin Hebert
@Colin Hebert,> = et <= pour être précis ;-)
aioobe
Vous m'avez probablement mal compris. Dans un monde meilleur, Double.MIN_VALUEserait égal à Double.NEGATIVE_INFINITY, car alors il serait cohérent avec MIN_VALUEles types entiers. Je pourrais initialiser n'importe quelle variable pour calculer un maximum avec MIN_VALUEet ce serait correct. Le que Double.MIN_VALUEnous avons maintenant aurait un meilleur nom. (Et de manière analogue pour MAX_VALUE.)
starblue
2

Parce qu'avec les nombres à virgule flottante, la précision est ce qui est important car il n'y a pas de plage exacte .

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

Mais je suis d'accord qu'il aurait probablement dû être nommé quelque chose de mieux :)

John Gardner
la source
OK, mais alors pourquoi est-il judicieux d'avoir Double.MAX_VALUE? Cela semble clairement défini.
mo-seph
parce que c'est la valeur précise maximale (non infinie), sans tenir compte de son signe.
John Gardner
0

Comme il est dit dans les documents ,

Double.MIN_VALUE est une constante contenant la plus petite valeur POSITIVE différente de zéro de type double, 2 ^ (- 1074).

L'astuce ici est que nous parlons d'une représentation numérique à virgule flottante. Le type de données double est une virgule flottante IEEE 754 64 bits à double précision. Les virgules flottantes représentent des nombres de 1 000 000 000 000 à 0,000000000000000001 avec facilité et en maximisant la précision (le nombre de chiffres) aux deux extrémités de l'échelle. (Pour en savoir plus, consultez ceci )

La mantisse, toujours un nombre positif , contient les chiffres significatifs du nombre à virgule flottante. L'exposant indique la puissance positive ou négative de la base par laquelle la mantisse et le signe doivent être multipliés. Les quatre composants sont combinés comme suit pour obtenir la valeur en virgule flottante.

entrez la description de l'image ici

Pensez que MIN_VALUE est la valeur minimale que la mantisse peut représenter. Comme les valeurs minimales d'une représentation en virgule flottante sont la grandeur minimale qui peut être représentée en utilisant cela. (J'aurais pu utiliser un meilleur nom pour éviter cette confusion)

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


Ci-dessous est juste FYI.

La virgule flottante double précision peut représenter 2 098 puissances de deux, de 2 ^ -1074 à 2 ^ 1023. Les puissances dénormalisées de deux sont celles de 2 ^ -1074 à 2 ^ -1023; les puissances normalisées de deux sont celles de 2 ^ -1022 à 2 ^ 1023. Reportez - vous ceci et cela .

premier
la source
Je vous remercie! Je ne sais pas pourquoi cette réponse a été rejetée.
Combinez