minyor
minyor

Reputation: 1037

How to write new value to individual bit without (if/else) operator

I know that I can set bit N by:

VALUE |= 1 << N;

Or clear bit N by:

VALUE &= ~(1 << N);

But what is the most efficient way to "write" (not set or clear) bit N? For example, I have a function:

__inline void writeBit(char &value, int N, bool state)
{
    if(state)
        value |= 1 << N;
    else
        value &= ~(1 << N);
}

Can I somehow get rid of if/else statements and instead do this only using binary and shift operators?

Upvotes: 2

Views: 400

Answers (2)

MSalters
MSalters

Reputation: 179779

I'd go for the simple solution:

inline void writeBit(char &value, int N, bool state)
{
   value &= ~(1 << N); // Unconditional clear. We don't care about old value.
   value |= char(state) << N; // Unconditional set to intended value. 
}

Since this is so clear and common, any decent optimizer will recognize the intent and use the best solution. Either of the two instructions will be useless, depending on state, but also harmless. That's better than the branch you have in your code.

I expect this to be better than either of dasblinkenlight's methods, unless an optimizer optimizes them all to the same.

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

The page of Bit Hacks suggests using the following formula:

value ^= (-state ^ value) & (1 << N);

The declaration of state needs to change from bool to an int.

This trick works on computers with twos complement representation of negative numbers, because unary minus -state changes the state 1 to a number composed of ones, and leaves zero unchanged.

An alternative for superscalar CPUs looks like this:

value = (value & ~(1 << N)) | (-state & (1 << N));

Upvotes: 3

Related Questions