问题
in one interview, they asked me, How do you set or reset a bit? This is a very simple question and I answered that.
After that they asked me, do that without branching. I dont know what is branching.
I search for that and I came here
http://graphics.stanford.edu/~seander/bithacks.html
But still not getting concept of branching and non-branching.
Please explain Branching.
回答1:
Branching means that the instructions the cpu executes contain a conditional jump. An either-or choice. Which could mean an if, a for-loop, while-loop, switch, ?: or something that makes a decision based on a boolean.
One class of branches that people often forget are also short-circuiting boolean operators and possibly (but not necessarily on all CPUs) things that evaluate to truth values, so int foo; ...; foo = !foo; will be a branch on some CPUs, but not all (not on x86).
So to set a bit:
i |= (1 << bit);
Reset a bit:
i &= ~(1 << bit);
Toggle a bit:
i ^= (1 << bit);
No branches. I actually don't see how to make this so complicated to have to use a branch.
The reason why someone might want to worry about branches is branch prediction. See this question and answer for an excellent explanation of why it matters.
回答2:
May be they wanted you to show how to write a generic set/reset snippet without branches...
This could be accomplished with
value = (value & ~(1 << bit)) | (bitval << bit);
where bit is the bit position and bitval is 1 for set and 0 for reset.
Something even slightly more general is the following:
value = (value & ~(k1 << bit)) ^ (k2 << bit);
that implements several operations:
k1=0andk2=0does nothingk1=0andk2=1toggles the bitk1=1andk2=0clears the bitk1=1andk2=1sets the bit
More generally with
value = (value & a) ^ x;
you can decide to change several bits of value at the same time by
aj=0,xj=0→ setting them to 0aj=0,xj=1→ setting them to 1aj=1,xj=0→ leaving them untouchedaj=1,xj=1→ flipping them
depending on the precomputed constants a and x (aj and xj are the value of the j-th bit in the constants).
For example
value = (value & 0x0F) ^ 0x3C;
with a single operation will
- leave untouched bit 0 and 1
- flip bits 2 and 3
- set to 1 bits 4 and 5
- set to 0 all other bits
来源:https://stackoverflow.com/questions/17803889/set-or-reset-a-given-bit-without-branching