Why is Double.MIN_VALUE in not negative
Asked Answered
M

6

201

Can anyone shed some light on why Double.MIN_VALUE is not actually the minimum value that Doubles can take? It is a positive value, and a Double can of course be negative.

I understand why it's a useful number, but it seems a very unintuitive name, especially when compared to Integer.MIN_VALUE. Calling it Double.SMALLEST_POSITIVE or MIN_INCREMENT or similar would have clearer semantics.

Also, what is the minimum value that Doubles can take? Is it -Double.MAX_VALUE? The docs don't seem to say.

Meadows answered 7/10, 2010 at 18:44 Comment(3)
Thanks for the responses! The difference between range and precision makes sense. I still find the naming quite strange and inconsistent, but it is workable.Meadows
I'm guessing because it's written by the same geniuses who called a method writeBytes which takes a String.Spinneret
Basically, you're right, it's bad semanticsKriemhild
K
220

The IEEE 754 format has one bit reserved for the sign and the remaining bits representing the magnitude. This means that it is "symmetrical" around origo (as opposed to the Integer values, which have one more negative value). Thus the minimum value is simply the same as the maximum value, with the sign-bit flipped, so yes, -Double.MAX_VALUE is the lowest actual number you can represent with a double.

I suppose the Double.MAX_VALUE should be seen as maximum magnitude, in which case it actually makes sense to simply write -Double.MAX_VALUE. It also explains why Double.MIN_VALUE is the least positive value (since that represents the least possible magnitude).

But sure, I agree that the naming is a bit misleading. Being used to the meaning Integer.MIN_VALUE, I too was a bit surprised when I read that Double.MIN_VALUE was the smallest absolute value that could be represented. Perhaps they thought it was superfluous to have a constant representing the least possible value as it is simply a - away from MAX_VALUE :-)

(Note, there is also Double.NEGATIVE_INFINITY but I'm disregarding from this, as it is to be seen as a "special case" and does not in fact represent any actual number.)

Here is a good text on the subject.

Killerdiller answered 7/10, 2010 at 18:53 Comment(3)
Thanks for this. I was porting some statistical analysis code and blindly translating java to C#. I noticed some numbers coming out at -infinity or NaN and took a closer look at the algorithm. I realized that double.MIN_VALUE made no sense in context and did a search. This post comes up before the java docs. It really is a confusing name for what really is double.Epsilon. Not a big deal, took less than a minute to fix, but definitely surprising.Bennington
Isn't the "smallest absolute value that can be represented" supposed to be named 'epsilon'?Oryx
@Sahuagin, it's not really "supposed" to be named anything particular. Epsilon is just a greek letter that commonly represents an arbitrarily small positive quantity in maths / physics. Go chose SmallestNonzeroFloat64 for instance.Killerdiller
T
14

These constants have nothing to do with sign. This makes more sense if you consider a double as a composite of three parts: Sign, Exponent and Mantissa. Double.MIN_VALUE is actually the smallest value Mantissa can assume when the Exponent is at minimun value before a flush to zero occurs. Likewise MAX_VALUE can be understood as the largest value Mantissa can assume when the Exponent is at maximum value before a flush to infinity occurs.

A more descriptive name for these two could be Largest Absolute (add non-zero for verbositiy) and Smallest Absolute value (add non-infinity for verbositiy).

Check out the IEEE 754 (1985) standard for details. There is a revised (2008) version, but that only introduces more formats which aren't even supported by java (strictly speaking java even lacks support for some mandatory features of IEEE 754 1985, like many other high level languages).

Thenna answered 7/10, 2010 at 19:10 Comment(0)
C
7

I assume the confusing names can be traced back to C, which defined FLT_MIN as the smallest positive number.

Like in Java, where you have to use -Double.MAX_VALUE, you have to use -FLT_MAX to get the smallest float in C.

Causeway answered 3/10, 2016 at 3:29 Comment(0)
B
5

The minimum value for a double is Double.NEGATIVE_INFINITY that's why Double.MIN_VALUE isn't really the minimum for a Double.

As the double are floating point numbers, you can only have the biggest number (with a lower precision) or the closest number to 0 (with a great precision).

If you really want a minimal value for a double that isn't infinity then you can use -Double.MAX_VALUE.

Boating answered 7/10, 2010 at 18:49 Comment(8)
Following that idea, is the maximum value for a Double Double.MAX_VALUE or Double.POSITIVE_INFINITY?Meadows
Double.MIN_VALUE could be equal to Double.NEGATIVE_INFINITY.Nne
@starblue, no. @mo-seph, Double.POSITIVE_INFINITY, +∞ > everything and —∞ < everythingBoating
@Colin Hebert, >= and <= to be precise ;-)Killerdiller
You probably misunderstood me. In a better world, Double.MIN_VALUE would be equal to Double.NEGATIVE_INFINITY, because then it would be consistent with MIN_VALUE in the integer types. I could initialize any variable for computing a maximum with MIN_VALUE and it would be correct. The Double.MIN_VALUE we have now would have a better name. (And analogously for MAX_VALUE.)Nne
@Meadows The maximum is Double.POSITIVE_INFINITY.Nne
@Killerdiller - Nothing equals infinity, not even infinity. So > and < are fine. ;)Bailly
@ishtar, not sure I follow you, Double.NEGATIVE_INFINITY < Double.NEGATIVE_INFINITY is false (obviously), but Double.NEGATIVE_INFINITY <= Double.NEGATIVE_INFINITY is true (obviously).Killerdiller
A
3

Because with floating point numbers, the precision is what is important as there's no exact range.

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

But i agree that it should probably have been named something better :)

Analyzer answered 7/10, 2010 at 18:50 Comment(2)
OK, but then why does it make sense to have Double.MAX_VALUE? That seems to be clearly defined.Meadows
because its the maximum precise value (non infinite), not accounting for its sign.Analyzer
A
1

As it says in the documents,

Double.MIN_VALUE is a constant holding the smallest POSITIVE nonzero value of type double, 2^(-1074).

The trick here is we are talking about a floating point number representation. The double data type is a double-precision 64-bit IEEE 754 floating point. Floating points represent numbers from 1,000,000,000,000 to 0.0000000000000001 with ease, and while maximizing precision (the number of digits) at both ends of the scale. (For more refer this)

The mantissa, always a positive number, holds the significant digits of the floating-point number. The exponent indicates the positive or negative power of the radix that the mantissa and sign should be multiplied by. The four components are combined as follows to get the floating-point value.

enter image description here

Think that the MIN_VALUE is the minimum value that the mantissa can represent. As the minimum values of a floating point representation is the minimum magnitude that can be represented using that. (Could have used a better name to avoid this confusion though)

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


Below is just FYI.

Double-precision floating-point can represent 2,098 powers of two, from 2^-1074 through 2^1023. Denormalized powers of two are those from 2^-1074 through 2^-1023; normalized powers of two are those from 2^-1022 through 2^1023. Refer this and this.

Arnelle answered 29/3, 2018 at 18:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.