Reputation: 1037
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
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
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