Smallest float different from 0.0?
dickinsm at gmail.com
Mon Sep 7 19:33:44 CEST 2009
On Sep 7, 5:08 pm, kj <no.em... at please.post> wrote:
> Hmmm. This close-to-the-metal IEEE stuff make a "HERE BE DRAGONS!"
> alarms go off in my head... (What's up with that correction by 1
> to sys.float_info.mant_dig? Or, probably equivalently, why would
> sys.float_info.min_exp (-1021) be off by 1 relative to log2 of
> sys.float_info.min (-1022)?)
The sys.float_info constants come straight from the standard C
limits defined in float.h. The C standards choose to describe
floats in the form
sign * 2**exponent * significand
with 0.5 <= significand < 1.0. (Well, assuming base 2; the
actual standard is a bit more general than this; see e.g.
section 126.96.36.199.2 of C99.)
So from C's point of view, the smallest normal value
comes from the minimum exponent (-1021) together with
the minimum significand (0.5), so it's 2**-1021 * 0.5,
or 2**-1022. Similarly, the max value is (1-2**-53)*2**1024.
It's a bit unfortunate that the IEEE 754 standard prefers
a different normalization, with the exponent chosen so that
the significand is in [1.0, 2.0). So where IEEE 754-2008
gives emax as 1023, C gives DBL_MAX_EXP as 1024; both
describing exactly the same format.
> I suppose that
> 2**(sys.float_info.min_exp - sys.float_info.mant_dig)
> would also work?
Yes. This all only works for IEEE 754 binary formats,
though. Most other floating-point formats you're likely
to meet (IBM hex floats, VAX D and G, Cray floats, etc.)
don't have gradual underflow and subnormals.
More information about the Python-list