WILCOX@nosc-tecr.arpa (05/28/89)
Assuming that the target machine implements two's compliment arithmetic
and doesn't have store condition code instructions, there is a simple
optimization that few C compilers seem to use. Given:
int a;
int b, c;
a = (b < c);
the usual approach is something like:
a = 0;
if( ! (b < c)) goto label;
a = 1;
label:
A better approach would seem to be:
a = (unsigned)((c - b) >> (WIDTH_OF_INT_IN_BITS - 1));
In other words, subtract rather than compare, and shift the resulting sign
bit into the least-significant bit position with zero extend. There is
also a variation using signed rather than unsigned shift, which generates
either -1 or 0, followed by an increment to produce either 0 or 1.
--Dwight Wilcox
Code 412
Naval Ocean Systems Center
San Diego, CA 92152-5000WILCOX@nosc-tecr.arpa (05/28/89)
Wooops! I was thinking of the signed form and got put "c - b" instead
of "b - c". Unsigned form should be:
a = (b < c); ==>
a = (unsigned)((b - c) >> (WIDTH_OF_INT_IN_BITS - 1));
--Dwight Wilcox
Code 412
Naval Ocean Systems Center
San Diego, CA 92152-5000augustss@cs.chalmers.se (Lennart Augustsson) (05/29/89)
In article <19787@adm.BRL.MIL> WILCOX@nosc-tecr.arpa writes: > > ... > int a; > int b, c; > a = (b < c); > > [ should be replaced by ] > >a = (unsigned)((b - c) >> (WIDTH_OF_INT_IN_BITS - 1)); > Good idea, but it doesn't work. Assuming 16 bit integers, take b = -32768; (0x8000) c = 32767; (0x7fff) now clearly b < c will evaluate to 1, but (unsigned)((b - c) >> 15 will evaluate to 0, since b-c evaluates to 1 (0x0001). -- Lennart Augustsson Lennart Augustsson Email: augustss@cs.chalmers.se or augustss@chalmers.csnet