Simple Bit Manipulation Macros

Stephen Friederichs March 12, 20134 comments Coded in C

Everyone working with low-level registers has needed to set, toggle and clear individual bits without disturbing the other bits.  This requires a simple but often difficult to remember series of ORs, ANDs and NOTs that are more often easier to just implement as a macro.  This code snippet implements macros to set a certain bit to '1', to clear a bit (set it to '0'), to toggle a bit (switch from '1' to '0' or '0' to '1') and to read the value of a bit.

/* Basic bit manipulation macros
   No one should ever have to rewrite these
*/

//Set bit y (0-indexed) of x to '1' by generating a a mask with a '1' in the proper bit location and ORing x with the mask.

#define SET(x,y) x |= (1 << y)

//Set bit y (0-indexed) of x to '0' by generating a mask with a '0' in the y position and 1's elsewhere then ANDing the mask with x.

#define CLEAR(x,y) x &= ~(1<< y)

//Return '1' if the bit value at position y within x is '1' and '0' if it's 0 by ANDing x with a bit mask where the bit in y's position is '1' and '0' elsewhere and comparing it to all 0's.  Returns '1' in least significant bit position if the value of the bit is '1', '0' if it was '0'.

#define READ(x,y) ((0u == (x & (1<<y)))?0u:1u)

//Toggle bit y (0-index) of x to the inverse: '0' becomes '1', '1' becomes '0' by XORing x with a bitmask where the bit in position y is '1' and all others are '0'.

#define TOGGLE(x,y) (x ^= (1<<y))

Comments:

Cryptoman
Said:
The macros in this snippet are useful and are often needed. However, if one uses too many of these macros, the code size will grow due to the excessive repetition of code. In such applications it may be worth implementing these macros as functions. Just to give an example, let's take the CLEAR(x,y) macro which can be turned into a function as follows. unsigned char clear_func( unsigned char y ) { x &= ~(1<< y); return x; }
6 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
nbrunner
Said:
Macros should use parameters surrounded by parenthesis. The whole macro should also surrounded by parenthesis. http://docs.freebsd.org/info/cpp/cpp.info.Macro_Parentheses.html
6 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
dszabo
Said:
I would frown upon using such macros. Whats harder, knowing how to do bit-manipulation (which you TOTALLY should know how to do anyway) or trying to remember the API for a set of macros that could very easily vary between implementations? Also, a function call would be silly. Do I really need a subroutine for something a processor can do in a single instruction? Thats less efficient in everyway I can think of.
6 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
ufSmartCoder
Said:
Operator Precedence!
SET ( myInt, pos & MASK);
wold mean:
myInt |= ((1 << y) & MASK);
better have:
SET(x,y) (x) |= (1 << (y))
3 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
Sorry, you need javascript enabled to post any comments.