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