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