Assuming x is a 8bit unsigned integer, what is the most efficient command to set the last two bits to 01
?
So regardless of the initial value it should be x = ******01
in the final state.
In order to set
- the last bit to 1, one can use OR like
x |= 00000001
, and - the forelast bit to 0, one can use AND like
x &= 11111101
which is~(1<<1)
.
Is there an arithmetic / logical operation that can be use to apply both operations at the same time?
Can this be answered independently of programm-specific implementation but pure logical operations?
CodePudding user response:
Of course you can put both operation in one instructions.
x = (x & 0b11111100) | 1;
That at least saves one assignment and one memory read/write. However, most likely the compilers may optimize this anyway, even if put into two instructions.
Depending on the target CPU, compilers may even optimize the code into bit manipulation instructions that directly can set or reset single bits. And if the variable is locally heavily used, then most likely its kept in register.
So at the end the generated code may look at as simple as (pseudo asm):
load x
setBit 0
clearBit 1
store x
however it also may be compiled into something like
load x to R1
load immediate 0b11111100 to R2
and R1, R2
load immediate 1 to R2
or R1, R2
store R1 to x
For playing with things like this you may throw a look at compiler explorer https://godbolt.org/z/sMhG3YTx9
Please try removing the -O2
compiler option and see the difference between optimized and non-optimized code. Also you may try to switch to different cpu architectures and compilers
CodePudding user response:
This is not possible with a dyadic bitwise operator. Because the second operand should allow to distinguish between "reset to 0", "set to 1" or "leave unchanged". This cannot be encoded in a single binary mask.
Instead, you can use the bitwise ternary operator and form the expression
x = 11111100 ??? x : 00000001
.
Anyway, a piece of caution: this operator does not exist.