"Marcelo E. Magallon" wrote:
>
> >> Jos� Fonseca <[EMAIL PROTECTED]> writes:
>
> > +#if 0
> > #define DIV255(X) (((X) << 8) + (X) + 256) >> 16
> > +#else
> > + const GLint temp;
> > +#define DIV255(X) (temp = (X), ((temp << 8) + temp + 256) >> 16)
>
> That function introduces an small error (off by +-1) in about 50% of
> the time for inputs in the range [0, 0xFFE1]. OTOH, this function (and
> its optimized equivalent):
>
> DIV255(X) ((X) + ((X) >> 8) + 0x80) >> 8
>
> introduces an small error (off by -1) in 0.2% of the cases, the error
> being the same as that introduced by the original function. This
> approximation is obtained in the following way:
>
> x/255
> = x/256*256/255
> = x/256 + x/(256*255)
> = x/256 + x/(256*256) + x/(256*256*255)
>
> the last factor is negligible in the range of interest. The expression
> can be then approximated by:
>
> (x + x/256)/256
>
> Since we are performing integer arithmeric:
>
> (x + x/256 + 128)/256
>
> to account for rounding up. The error is well spread over the last
> half of the range. This can be coded in 16 bit arithmetic while the
> original needs 24 bits.
Hmmm, I wrote a little test program to compare the original macro:
#define DIV255(X) (((X) << 8) + (X) + 256) >> 16
and yours:
#define DIV255(X) ((X) + ((X) >> 8) + 0x80) >> 8
to a simple integer divide.
The original is always correct for integers in [0, 255*255] while yours
is frequently off by one.
Here's the program:
#include <stdio.h>
#define DIV255a(X) (((X) << 8) + (X) + 256) >> 16
#define DIV255b(X) (((X) + ((X) >> 8) + 0x80) >> 8)
int main(int argc, char *argv[])
{
int i;
for (i = 0; i <= 255 * 255; i++) {
int d0 = i / 255;
int d1 = DIV255a(i);
int d2 = DIV255b(i);
if (d0 != d1 || d0 != d2)
printf("%5d: %d %d %d\n", i, d0, d1, d2);
}
return 0;
}
-Brian
_______________________________________________
Dri-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/dri-devel