"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