[Python-Dev] small floating point number problem

Bengt Richter bokr at oz.net
Wed Feb 8 16:54:38 CET 2006


On 2006年2月08日 03:08:25 -0500, "Raymond Hettinger" <raymond.hettinger at verizon.net> wrote:
>[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
>BTW, for the OP, chasing minimum float values is probably best done with powers of 2
 >>> math.ldexp(1, -1074)
 4.9406564584124654e-324
 >>> math.ldexp(1, -1075)
 0.0
 >>> .5**1074
 4.9406564584124654e-324
 >>> .5**1075
 0.0
 >>> math.frexp(.5**1074)
 (0.5, -1073)
 >>> math.frexp(.5**1075)
 (0.0, 0)
Regards,
Bengt Richter


More information about the Python-Dev mailing list

AltStyle によって変換されたページ (->オリジナル) /