C/C++ Bit Twiddling
in the spirit of graphics.stanford.edu/~seander/bithacks.html I need to solve the following problem:
int x;
int pow2; // always a positive power of 2
int sgn; // always either 0 or 1
// ...
// ...
if(sgn == 0)
x -= pow2;
else
x += pow2;
Of course I need to avoid the conditional. So far the best I came up with is
x -= (1|(~sgn+1))*pow2
but that involves a multiplication which I also would like to avoid. Thanks in advance.
EDIT: Thanks a开发者_JAVA百科ll,
x -= (pow2^-sgn) + sgn
seems to do the trick!
I would try
x -= (pow2 ^ (~sgn+1)) + sgn
or, as suggested by lijie in the comments
x -= (pow2 ^ -sgn) + sgn
If sgn
is 0
, ~sgn+1
is also 0
, so pow2 ^ (~sgn+1) == pow2
. If sgn
is 1
, (~sgn+1)
is 0xFFFFFFFF
, and (pow2 ^ (~sgn+1)) + sgn == -pow2
.
mask = sgn - 1; // generate mask: sgn == 0 => mask = -1, sgn == 1 => mask = 0
x = x + (mask & (-pow2)) + (~mask & (pow2)); // use mask to select +/- pow2 for addition
Off the top of my head:
int subMask = sgn - 1;
x -= pow2 & subMask;
int addMask = -sgn;
x += pow2 & addMask;
No guarantees on whether it works or whether this is smart, this is just a random idea that popped into my head.
EDIT: let's make this a bit less readable (aka more compact):
x += (pow2 & -sgn) - (pow2 & (sgn-1));
I would change the interface and replace the multiplication by left shift. (Use exponent instead of pow2)
You can do something like (from the link) x += ((pow2 ^ -sgn) + sgn)
精彩评论