If they are not you can join those two techniques to form !a ^ !b which
is probably faster then !a != !b because no branching is used (at least
on some architectures).
I don't know of any architecture where ! doesn't need conditional
branching (the kind that usually matters here) but != does.
But, I assume that if at least one of the values (say a) is boolean the
following will be even faster: ((unsigned)(((signed)a)-1)) & b. Not
sure if it's not implementation specific though. (If neither is boolean
replace a with !a). Disadvantage is that if b is not boolean this will
not produce a boolean value.
Doesn't do XOR for a==1 b==0. You can do & but I'm pretty sure you
can't get nonboolean ^ to work because it's (algebraically) linear.
The casts aren't needed if either a or b is unsigned (and not stricly
narrower than int). unsigned_a - 1 wraps around safely. signed_a - 1
gives an in-range signed value which automatically converts to
unsigned when it meets unsigned_b across & . If both are signed using
a -1U is enough to force (everything) unsigned (unless strictly wider
than int, then you need -1UL or even -1ULL). Using the casts is
arguably clearer, but if any of your nonbooleans are (or may be) wider
than int you have to specify appropriately wide typenames.
I think the only way to do this for XOR is to fully smear the/each
nonboolean operand e.g.
aa = a; aa |= aa >> 1; aa |= aa >> 2; aa |= aa >> 4; etc.
bb = b similarly if necessary
aa ^ bb
You can shorten the dependency chain (which is limiting on some
(most?) modern architectures) by doing somewhat more computation:
aa = a; aa |= aa >> 1 | aa >> 2; aa |= aa >> 3 | aa >> 6; etc.
- formerly david.thompson1 || achar(64) || worldnet.att.net