Re: [Tutor] small floating point number problem

2006-02-10 Thread Bengt Richter
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


[Tutor] small floating point number problem

2006-02-07 Thread 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
 a==0
True-- it really is 0; this is not a repr issue
 b=.1*1e-307
 b
9.9991e-309
 a==b
False--they really are different
 

Also, I see that there is some graininess in the numbers at the low end, but 
I'm guessing that there is some issue with floating points that I would need to 
read up on again. The above dilemma is a little more troublesome.

 m=2.470328229206234e-017
 s=1e-307
 m*s
4.9406564584124654e-324 #2x too large
 2*m*s
4.9406564584124654e-324
 3*m*s==4*m*s
True
 

/c

___
Tutor maillist  -  Tutor@python.org
http://mail.python.org/mailman/listinfo/tutor