[Python-Dev] small floating point number problem

Raymond Hettinger raymond.hettinger at verizon.net
Wed Feb 8 09:08:25 CET 2006


[Smith]
>I just ran into a curious behavior with small floating points, trying to 
>find the limits of them on my machine (XP). Does anyone know why the '0.0' 
>is showing up for one case below but not for the other? According to my 
>tests, the smallest representable float on my machine is much smaller than 
>1e-308: it is
>
> 2.470328229206234e-325
>
> but I can only create it as a product of two numbers, not directly. Here 
> is an attempt to create the much larger 1e-308:
>
>>>> a=1e-308
>>>> a
> 0.0

The clue is in that the two differ by 17 orders of magnitude (325-308) which 
is about 52 bits.

The interpreter builds 1-e308 by using the underlying C library 
string-to-float function and it isn't constructing numbers outside the 
normal range for floats.  When you enter a value outside that range, the 
function underflows it to zero.

In contrast, your computed floats (such as 1*1e-307) return a denormal 
result (where the significand is stored with fewer bits than normal because 
the exponent is already at its outer limit).  That denormal result is not 
zero and the C library float-to-string conversion successfully generates a 
decimal string representation.

The asymmetric handling of denormals by the atof() and ftoa() functions is 
why you see a difference.  A consequence of that asymmetry is the breakdown 
of the expected eval(repr(f))==f invariant:

>>> f = f = .1*1e-307
>>> eval(repr(f)) == f
False



Raymond 



More information about the Python-Dev mailing list