[XviD-devel] Rounding
skal
xvid-devel@xvid.org
31 Oct 2002 10:31:50 +0100
Hi all,
since the discussion has settled to what looks like
an agreement, I think it's time to get messier :)
I made some tests in order to determine what I could
positively be 100% sure(*), and it appears that:
a) operator '/2' (truncation toward 0):
there at least 3 equivalent ways of compute 'y=x/2':
Reference:
y = 0.5f*x;
if (x<0) y=-y;
y = (int)floor(y);
if (x<0) y = -y;
bitwise shift:
y = (x+(x<0))>>1;
gcc-like:
y = x/2;
(ISO-C does not define the integer division between operand
of opposite signs, but gcc does is 'correctly' using the bitwise
shift above)(with a CMOV instr., btw)
b) operator '//2' (round away from zero to nearest integer)
There at least 4 equivalent ways of compute 'y=x//2':
Reference:
y = 0.5f*x;
if (x<0) y=-y;
y = (int)floor(y+.5f);
bitwise shift:
y = (x+(x>=0))>>1;
or equivalently:
y = (x+1-(x<0))>>1;
gcc-like:
y = (x+1)/2 - (x<0);
c) operator '////2' (truncation toward minus infinity)
(used for half/qpel snapping, for instance)
This one's rather easy:
Reference:
y = ((x&1)==0) ? x/2 : (x-1)/2;
bitwise shift:
y = (x>>1);
Now, bearing that in mind, it seems that:
On Wed, 2002-10-30 at 11:08, skal wrote:
> >
>
> Arghhh... I think I mess with the tables, indeed. I was using
> the OR because it's sometime faster than arithmetic operations
> (e.g. on Sparcs if I remember well). It's really a coincidence
> the ' (x>>1)+ Rnd_Tab_79[x&3]' works for qpel -> halpel.
>
using Rnd_Tab_78 in replacement for either '/2 + Rnd_Tab_79[]'
or '//2 + Rnd_Tab_79[]' will not work for qpel 'divide before
summation' K=1 case. The problem shows up when (x&7)==7,
since Tab_78[(x&7)] = 1, whereas Tab_79[(x>>1)&3] = 0.
hope I messed things up properly :)
bye,
Skal
(*) 100% sure meaning, of course, that I'm ready to pay a beer to
the first that can prove me wrong ;)