Path: utzoo!attcan!uunet!lll-winken!lll-tis!helios.ee.lbl.gov!pasteur!ucbvax!decwrl!labrea!sri-unix!quintus!ok From: ok@quintus.uucp (Richard A. O'Keefe) Newsgroups: comp.lang.c Subject: Re: Shifting question Message-ID: <178@quintus.UUCP> Date: 20 Jul 88 04:35:17 GMT References: <705@bnr-rsc.UUCP> <11556@steinmetz.ge.com> <60290@sun.uucp> <1818@spar.SPAR.SLB.COM> Sender: news@quintus.UUCP Reply-To: ok@quintus.UUCP (Richard A. O'Keefe) Organization: Quintus Computer Systems, Inc. Lines: 50 In article <1818@spar.SPAR.SLB.COM> hunt@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.)