floor() function and mathematical integers

Bengt Richter bokr at accessone.com
Sun May 27 11:03:22 EDT 2001


On 25 May 2001 09:23:38 -0700, aahz at panix.com (Aahz Maruch) wrote:

>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.
>
[...]
>    # 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
>
UIAM, since digit has the last non-zero chunk, you could let the FPU
count the trailing bits instead of using a while loop:

    trailing_bits = math.frexp(float(digit^(digit-1)))[1]-1
    top >>= trailing_bits
    e += trailing_bits

FWIW, I think you could speed up the decimal trailing zero trim too.
What's the biggest number of possible trailing decimal zeroes? 22?
Of course, this would slow things down when there's no or few zeroes.
Adjust kzlog2 to taste. BTW, what's the preferred style for avoiding
"magic numbers" in python code, with no #define SOME_CONSTANT?

I have in mind replacing
>    # Nuke trailing (decimal) zeroes.
>    while 1:
>        assert top > 0
>        newtop, rem = divmod(top, 10L)
>        if rem:
>            break
>        top = newtop
>        e = e + 1
>
with something like:

    # Nuke trailing (decimal) zeroes.
    kzlog2 = 4
    zlog2 = kzlog2 #log2 of zeroes possibly removed in curr loop
    while zlog2 >=0:
        assert top > 0
        newtop, rem = divmod( top, 10L**(1<<zlog2) )
        if not rem:
            top = newtop
            e = e + (1<<zlog2)
        if zlog2 != kzlog2 or rem: #wait for rem at biggest chunk
            zlog2 -= 1

For an IEEE 754 double I suspect you could drop the last if condition.

Another (python- ;-) newbie blurt: is it possible in python to define
your own binary  (and unary too, for that matter) operator symbols?

Building on the % operator syntax, it might be nice to define
named operators as name% so that you could, e.g., define
a vector class using '*' for scalar multiply, but 'X%' or
maybe VXP% for cross product, by defining __mul__ and __X__
( or __VXP__ ). It'd be nice to be able to control associativity
and precedence too.

Just defining the function __X__ in a particular scope would mean
that a X% b would invoke __X__(a,b) or __X__(b) or __X__(a) depending
on how it was defined.

Would this ripple coolly or disastrously?

I liked the 5L**-e thing. That was nice to see. Rung a bell,
though I can't recall from where right now.




More information about the Python-list mailing list