Decimal ROUND_HALF_EVEN Default

Bengt Richter bokr at oz.net
Tue Jan 17 14:06:25 EST 2006


On 16 Jan 2006 20:36:12 -0800, "Raymond Hettinger" <python at rcn.com> wrote:

>LordLaraby wrote:
>> If 'bankers rounding' is HALF_ROUND_EVEN, what is HALF_ROUND_UP? I
>> confess to never having heard the terms.
>
>The terms are defined in the docs for the Context object:
>    http://docs.python.org/lib/decimal-decimal.html
>
>The rounding option is one of:
>------------------------------
>ROUND_CEILING (towards Infinity),
>ROUND_DOWN (towards zero),
>ROUND_FLOOR (towards -Infinity),
>ROUND_HALF_DOWN (to nearest with ties going towards zero),
>ROUND_HALF_EVEN (to nearest with ties going to nearest even integer),
>ROUND_HALF_UP (to nearest with ties going away from zero), or
>ROUND_UP (away from zero).
>
>
>> I usually do: Y = int(X + 0.5) scaled to proper # of decimal places.
>> Which type of rounding is this? If either.
>
>The interpreter shows that ties are rounded down towards zero:
>
>>>> [int(x + 0.5) for x in range(-5, 6)]
>[-4, -3, -2, -1, 0, 0, 1, 2, 3, 4, 5]
>
Or more explicitly:
 >>> for x in xrange(-5,6): print 'int(%2s + 0.5) == int(%4s) => %2s'%(x,x+.5,int(x+.5))
 ...
 int(-5 + 0.5) == int(-4.5) => -4
 int(-4 + 0.5) == int(-3.5) => -3
 int(-3 + 0.5) == int(-2.5) => -2
 int(-2 + 0.5) == int(-1.5) => -1
 int(-1 + 0.5) == int(-0.5) =>  0
 int( 0 + 0.5) == int( 0.5) =>  0
 int( 1 + 0.5) == int( 1.5) =>  1
 int( 2 + 0.5) == int( 2.5) =>  2
 int( 3 + 0.5) == int( 3.5) =>  3
 int( 4 + 0.5) == int( 4.5) =>  4
 int( 5 + 0.5) == int( 5.5) =>  5

So one must be careful not to use int to convert relative screen positions to relative pixel deltas
to add to some pixel screen position, even when it's a single add that can't accumulate error or
round differentely after the add.

I guess one would want
 >>> for x in xrange(-5,6): print 'int(math.floor(%4s)) => %2s'%(x+.5,int(math.floor(x+.5)))
 ...
 int(math.floor(-4.5)) => -5
 int(math.floor(-3.5)) => -4
 int(math.floor(-2.5)) => -3
 int(math.floor(-1.5)) => -2
 int(math.floor(-0.5)) => -1
 int(math.floor( 0.5)) =>  0
 int(math.floor( 1.5)) =>  1
 int(math.floor( 2.5)) =>  2
 int(math.floor( 3.5)) =>  3
 int(math.floor( 4.5)) =>  4
 int(math.floor( 5.5)) =>  5

Which ISTM is the way some other int conversions have worked, but I can't recall the context ATM.
I.e., just trim the fractional bits from the theoretical fixed point twos complement number, which
always subtracts those positive-value fractional bits algebraically.

Regards,
Bengt Richter



More information about the Python-list mailing list