fs.
fs.

Reputation: 918

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 all,

x -= (pow2^-sgn) + sgn

seems to do the trick!

Upvotes: 15

Views: 1533

Answers (5)

Sven Marnach
Sven Marnach

Reputation: 601351

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.

Upvotes: 16

Rajivji
Rajivji

Reputation: 315

You can do something like (from the link) x += ((pow2 ^ -sgn) + sgn)

Upvotes: 1

stacker
stacker

Reputation: 68942

I would change the interface and replace the multiplication by left shift. (Use exponent instead of pow2)

Upvotes: 1

EboMike
EboMike

Reputation: 77722

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)); 

Upvotes: 2

Paul R
Paul R

Reputation: 212929

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

Upvotes: 4

Related Questions