On Wed, 08 Feb 2006 03:08:25 -0500, Raymond Hettinger [EMAIL PROTECTED]
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
___
Tutor maillist - Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor