floor() function and mathematical integers
Aahz Maruch
aahz at panix.com
Fri May 25 12:23:38 EDT 2001
In article <3b0e6e65.279481372 at wa.news.verio.net>,
Bengt Richter <bokr at accessone.com> wrote:
>
>Decided to add fractional float bit printing. Just started playing
>with Python, as you can probably tell. No warranty.
For comparison, take a look at this routine from Tim Peters to convert
floats to strings (yes, Tim, I modified it to work with 1.5.2):
def _floatToString(x):
"""Return float x as exact decimal string.
The string is of the form:
"-", if and only if x is < 0.
One or more decimal digits. The last digit is not 0 unless x is 0.
"e"
The exponent, a (possibly signed) integer
"""
import math
# XXX ignoring infinities and NaNs for now.
if x == 0:
return "0e0"
sign = ""
if x < 0:
sign = "-"
x = -x
f, e = math.frexp(x)
assert 0.5 <= f < 1.0
# x = f * 2**e exactly
# Suck up CHUNK bits at a time; 28 is enough so that we suck
# up all bits in 2 iterations for all known binary double-
# precision formats, and small enough to fit in an int.
CHUNK = 28
top = 0L
# invariant: x = (top + f) * 2**e exactly
while f:
f = math.ldexp(f, CHUNK)
digit = int(f)
assert digit >> CHUNK == 0
top = (top << CHUNK) | digit
f = f - digit
assert 0.0 <= f < 1.0
e = e - CHUNK
assert top > 0
# Now x = top * 2**e exactly. Get rid of trailing 0 bits if e < 0
# (purely to increase efficiency a little later -- this loop can
# be removed without changing the result).
while e < 0 and top & 1 == 0:
top = top >> 1
e = e + 1
# Transform this into an equal value top' * 10**e'.
if e > 0:
top = top << e
e = 0
elif e < 0:
# Exact is top/2**-e. Multiply top and bottom by 5**-e to
# get top*5**-e/10**-e = top*5**-e * 10**e
top = top * 5L**-e
# Nuke trailing (decimal) zeroes.
while 1:
assert top > 0
newtop, rem = divmod(top, 10L)
if rem:
break
top = newtop
e = e + 1
return "%s%de%d" % (sign, top, e)
More information about the Python-list
mailing list