You are making the classical mistake in thinking that less lines in C means more optimised code.
You should really examine the assembler output and profile your code to see if it's an actual bottleneck.
What I tend to do is optimise for readability first then only attack performance if it becomes an issue. So, a more readable solution (in my not so humble opinion) would be something like:
unsigned int bit_swap (unsigned int num, unsigned int pos1, unsigned int pos2) {
// Swapping identical bit positions is a no-op.
if (pos1 == pos2)
return num;
// Get masks from bit positions.
unsigned int mask1 = 1 << pos1;
unsigned int mask2 = 1 << pos2;
// Get bit truth values.
int bit1_was_set = ((num & mask1) != 0);
int bit2_was_set = ((num & mask2) != 0);
// Clear and set first bit (set only if second bit was originally set).
num = num & ~mask1;
if (bit2_was_set)
num = num | mask1;
// Do the same for other bit.
num = num & ~mask2;
if (bit1_was_set)
num = num | mask2;
// Return the value with swapped bits.
return num;
}
Despite having far more lines than your approach, you may well find the insanely optimising compilers available nowadays will give you similar code under the covers.
What you almost certainly will discover is that non-C-guru people (and possibly yourself, six months from now) will be able to understand your source code better than a single line multi-bitwise-operator variant.
if?pos1andpos2or something similar, as given in some answers. Additionally, it is usually a good idea to use unsigned ints when handling single bits, at least if you want your code to be portable. But this depends on what you need this for, just be aware that you may run into problems with negative values.& has lower precedence than ==; == will be evaluated first [-Wparentheses]inif(num & (1 << sbit) == num & (1 << dbit)).