Shifting question

Richard A. O'Keefe ok at quintus.uucp
Wed Jul 20 14:35:17 AEST 1988


In article <1818 at spar.SPAR.SLB.COM> hunt at spar.UUCP (Neil Hunt) writes:
>shift_pixel(image, count)
>    struct image *image;
>    int count;
>    {
>	int i, j;
>
>	for(j = 0; j < image->rows; j++)
>		for(i = 0; i < image->cols; i++)
>			image->pixels[i][j] >>= count;
>    }
>... the last line has to be:
>
>			if(count > 0)
>				image->pixels[i][j] >>= count;
>			else
>				image->pixels[i][j] <<= -count;
>
It is better to move the "if" outside the loop.
C arrays using the Algol convention rather than the Fortran one,
it may be better to vary j faster than i (and it might be faster
still to use pointers).

void shift_pixel(image, count)
    struct image *image;
    int count;
    {
	int i, j;

	if (count > 0) {
	    for (i = image->cols; --i >= 0; )
		for (j = image->rows; --j >= 0; )
		    image->pixels[i][j] >>= count;
	} else
	if (count < 0) {
	    count = -count;
	    for (i = image->cols; --i >= 0; )
		for (j = image->rows; --j >= 0; )
		    image->pixels[i][j] <<= count;
	}
    }

The bottom line is that because the C standard specifies that shifting
is undefined for negative or overlarge shift counts, it can generate
**faster** code for (this version of) the operation you want than it
could if shifting were more tightly specified.  Since several machines
take the bottom N bits of the shift count and assume it is negative,
if you didn't write the if somewhere, the compiler would have to, and
putting that if (count > 0) shift right; else shift left; in the inner
loop would really hurt pipelined and vectored machines.  (Unless the
compiler was smart enough to move the test outside the loop, of course.)



More information about the Comp.lang.c mailing list