Bitwise Operators in C

I wrote code to replace the bit positions (source bit and destination bit) .. it works fine .. But is there any optimized code for this?

int bit_swap(int num, int sbit, int dbit) { if(num & (1 << sbit) == num & (1 << dbit)) return num; else return (num ^ ((1 << sbit) | (1 << dbit))); } 

Here .. num is the entry number. sbit is the position of the source bit, and bit is the position of the destination bit.

Is it possible to write this code on one line without using if else

+4
source share
3 answers

No conditional version.

 int bit_swap(int num, int sbit, int dbit) { int sval = !!(num & (1 << sbit)); // sets to 1 iff the s-bit is already set int dval = !!(num & (1 << dbit)); // sets to 1 iff the d-bit is already set int xorval = (sval ^ dval); // sets to 1 if (sval != dval), otherwise 0 // so if xorval is 1, then it will toggle the bits at the S and D positions // otherwise, the expression below evalutes to "num" that was passed in return (num ^ ((xorval << sbit) | (xorval << dbit))); } 
+6
source

You make a classic mistake thinking that fewer lines in C mean more optimized code.

You should really check the assembler output and profile your code to see if this is really a bottleneck.

What I usually do is optimize for readability, and then only attack performance if that becomes a problem. So a more readable solution (in my not very humble opinion) would be something like this:

 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; } 

Although you have a lot more lines than your approach, you can find the insanely optimizing compilers currently available will provide you with similar code under the covers.

What you will almost certainly find is that people who are not C-gurus (and perhaps themselves in six months) will be able to better understand your source code than the option with several bit operations with one line.

+12
source

I figured it out

 unsigned swapBits(unsigned num, int sbit, int dbit) { return ( num & // All bits ~((1<<sbit) | (1<<dbit))) // Except sbit and dbit | (((num>>sbit)&1)<<dbit) // but with sbit moved to dbit | (((num>>dbit)&1)<<sbit); // and with dbit moved to sbit } 

I had ARM in mind, with its cheap shifts.

+2
source

All Articles