floor() function and mathematical integers

Bengt Richter bokr at accessone.com
Thu May 24 13:29:56 EDT 2001


On Fri, 18 May 2001 07:02:29 -0400, "Tim Peters" <tim.one at home.com>
wrote:
[...]
>
>The mathematical definition of floor(M * B**E) for non-negative integers M, B
>and E is M*B**E, and math.floor() does rigorously honor that.  You want
>something floating point doesn't address at all.
>
# Well, rigorously within limits ;-) :
 >>> import math
 >>> M=5L; B=3L; E=33L
 >>> a = M*B**E
 >>> a,float(a),math.floor(a)
 (27795302832777615L, 27795302832777616.0, 27795302832777616.0)
 >>> prb(a)
 1100010101111111010111000111111110001011010100110001111
 >>> prb(float(a))
 1100010101111111010111000111111110001011010100110010000
 >>> prb(math.floor(a))
 1100010101111111010111000111111110001011010100110010000
 >>> prb((2L**53 -1)*4)
 1111111111111111111111111111111111111111111111111111100
 >>> prb( float(2L**53-1)*4)
 1111111111111111111111111111111111111111111111111111100
 >>>
Float can't represent a accurately. I chose M and B to be odd,
so that there would always be a LSB of 1. The result takes more
than 53 bits (55) to represent, so bits below 53 are rounded
by float(), which apparently is happening automatically for the
call to math.floor(). BTW, the problem here is not in math.floor(),
it's that the theoretical value is not preserved in the
conversion to float before floor() is called.

If you restrict M to 53 bits of precision, B to a value of two,
and E to its almost 10-bit range, then I think what you say is true,
which I guess is what you meant ;-)

For grins, here's a little experiment result:

53 bits of precision is available to store doubles. Here's
what happpens when you are dealing with numbers that take 55 bits.
(The -64 is to catch the carry, so things will stay aligned)
prb just prints a long integer in binary.

 >>> prb(      (2L**53-1)*4-64)
 1111111111111111111111111111111111111111111111110111100
 >>> prb( float(2L**53-1)*4-64)
 1111111111111111111111111111111111111111111111110111100

 >>> prb(      (2L**53-1)*4-64 +1)
 1111111111111111111111111111111111111111111111110111101
 >>> prb( float(2L**53-1)*4-64 +1)
 1111111111111111111111111111111111111111111111110111100

 >>> prb(      (2L**53-1)*4-64 +2)
 1111111111111111111111111111111111111111111111110111110
 >>> prb( float(2L**53-1)*4-64 +2)
 1111111111111111111111111111111111111111111111111000000

 >>> prb(      (2L**53-1)*4-64 +3)
 1111111111111111111111111111111111111111111111110111111
 >>> prb( float(2L**53-1)*4-64 +3)
 1111111111111111111111111111111111111111111111111000000

 >>> prb(      (2L**53-1)*4-64 +4)
 1111111111111111111111111111111111111111111111111000000
 >>> prb( float(2L**53-1)*4-64 +4)
 1111111111111111111111111111111111111111111111111000000

 >>> prb(      (2L**53-1)*4-64 +7)
 1111111111111111111111111111111111111111111111111000011
 >>> prb( float(2L**53-1)*4-64 +7)
 1111111111111111111111111111111111111111111111111000100

 >>> prb(      (2L**53-1)*4-64 +8)
 1111111111111111111111111111111111111111111111111000100
 >>> prb( float(2L**53-1)*4-64 +8)
 1111111111111111111111111111111111111111111111111000100
 >>>




More information about the Python-list mailing list