Reputation: 857
I tried to determine DBL_MIN in a loop (in order to test another issue) and I was surprised by the output:
double tmp(1.0);
double min(tmp);
while(tmp>0)
{
tmp/=2.0;
if(tmp>0) min=tmp;
else break;
}
cout<<scientific<<endl;
cout<<"Computed minimum: "<<min<<endl;
cout<<"Defined minimum: "<<DBL_MIN<<endl;
if(min>0 && min<DBL_MIN) cout<<"min is between 0 and DBL_MIN, HUH!"<<endl;
exit(1);
The output is:
Computed minimum: 4.940656e-324
Defined minimum: 2.225074e-308
min is between 0 and DBL_MIN, HUH!
How can min hold the value 4.94e-324 when the smallest positive value is 2.2e-308 ? To my understanding positive values below DBL_MIN should not representable. Tested with GCC 4.9.2 on a Core i7 under Linux.
Upvotes: 3
Views: 250
Reputation: 10007
DBL_MIN
is minimum normalized positive value of double. This means that this is the minimum value that has its mantissa not less than 1.0
. You can still go for smaller numbers if you choose smaller mantissa.
So what you get is Denormal number. As Wikipedia puts it,
In a normal floating-point value, there are no leading zeros in the significand; instead leading zeros are moved to the exponent. So 0.0123 would be written as 1.23 × 10−2. Denormal numbers are numbers where this representation would result in an exponent that is below the minimum exponent (the exponent usually having a limited range). Such numbers are represented using leading zeros in the significand.
The IEEE 754 standard governs the representation of double
(and other floating-point types). The representation consists of exponent e
and mantissa m
(and sign bit, which is irrelevant for this question).
For the exponent e
not equal to zero, the corresponding double
value is
(1 + m/2^52) * 2^(e-1023)
(^
stands for power, and 52 is the number of bits in m
, so that m/2^52
is always between 0 inclusive and 1 non-inclusive). The implicit (not included in m
) 1
means that the minimal number that can be stored this way corresponds to m==0
and e==1
(remember that e!=0
for this representation), which gives the value of
2^(-1022)
which is approx. 2.225074e-308
, that is DBL_MIN
.
However, e==0
is treated in a special way. For e==0
, the implicit 1
is dropped, resulting in
(m / 2^52) * 2^(-1022) // remember that e==0
This allows for representation of exact zero (with m==0
), and also for subnormals (or denormals) for small m
. The smallest possible such number is for m==1
, that is 2^(-1074)
, or approx. 4.940656e-324
.
Upvotes: 2