Decimal arithmetic, with example code

Bengt Richter bokr at oz.net
Thu Oct 3 20:51:40 EDT 2002


On 3 Oct 2002 18:16:55 GMT, bokr at oz.net (Bengt Richter) wrote:

>On 3 Oct 2002 07:08:38 GMT, bokr at oz.net (Bengt Richter) wrote:
>[...]
>>
>>BTW, you probably noticed I wasn't really rounding in my evenround function --
>>I was just noodging the value so the subsequent round inside %.f looked like it
>>was doing decimal bankers round. I just played a hunch with the BIAS multiply.
>>Using FixedPoint as a final formatter for floating point should work better than
>>bias-kludging the ordinary round. It's probably about as good an estimate of the
>>nearest decimal of a given precision to a given fp number as you can get.
>>
>[...]
>>
>>BTW, FWIW, since the denominator is 1L << -e where you round the conversion,
>>the following should hold (I think, not very tested):
>>
>>                exactHalf = 1L << (-e-1)
>>                n = top + exactHalf    # ok round except banker's tie with odd no
>>                wasTie = not (n & ((exactHalf<<2)-1L))  # odd => even and no 1's below
>>                n = (n >> -e) - wasTie # readjust for bad tie result
>>
>>                assert n == _roundquotient(top, 1L << -e)
>>
>>Whether it's worth doing depends on speeds which I haven't tested. Depends on divmod and cmp...
>>Out of steam for tonight...
>>
>Not enough steam to get it right ;-/ -- this should work better and faster:
>
>                exactHalf = 1L << (-e-1)
>                wasTie = not (top & (exactHalf-1L))  #  no 1's below
>                n = top + exactHalf     # ok round except banker's tie => odd
>                n = (n >> -e)
>                n -= n & wasTie         # readjust for bad tie result
>                assert n == _roundquotient(top, 1L << -e)
>
Sheesh ;-0
                exactHalf = 1L << (-e-1)
                wasTie = (top & ((exactHalf<<1)-1L))==exactHalf
                n = top + exactHalf     # ok round except banker's tie => odd
                n = (n >> -e)
                n -= n & wasTie         # readjust for bad tie result
                assert n == _roundquotient(top, 1L << -e)

I was too anxious to avoid the shift. Thanks for not stomping all over me ;-)
I'm testing a debugging class using sys.settrace, so the above is not getting thorough
attention, except that I can now look at it with the new tool ;-)

>
>>BTW2, I wonder if it would be worth while to do a banker's round like round, but guaranteeing
>>that the result's magnitude will be the first fp state >= the true decimal value. It would
>>be biased minisculely, but it might be helpful for printing non-surprising decimals. str(f)
>>seems to be solving part of the problem, but an alternate %f (%F?) to control bankers round
>>at a given precision might be nice. A few bits from fixedpoint could be cannibalized.
>>

Regards,
Bengt Richter



More information about the Python-list mailing list