Bitwise work can be confusing if you don't have something like below to clear up the syntax of picking out individual bit values.
Code:
#include <stdio.h>
#include <limits.h>
#define BIT(n) ( 1UL << ( n ) )
int get_bit(unsigned long x, int i)
{
return !!( x & BIT ( i ) );
}
unsigned long set_bit(unsigned long x, int i, int bit)
{
if ( i < sizeof x * CHAR_BIT && i >= 0 ) {
if ( bit ) /* Set the bit */
x = ( get_bit ( x, i ) ) ? x : x | BIT ( i );
else /* Clear the bit */
x = ( get_bit ( x, i ) ) ? x &= ~BIT ( i ) : x;
}
return x;
}
int main ( void )
{
int i = 0;
printf ( "Bit 0: %d\n", get_bit ( i, 0 ) );
i = set_bit ( i, 0, 1 );
printf ( "Set 0: %d\n", i );
printf ( "Bit 1: %d\n", get_bit ( i, 1 ) );
i = set_bit ( i, 1, 1 );
printf ( "Set 1: %d\n", i );
printf ( "Bit 3: %d\n", get_bit ( i, 2 ) );
i = 0;
i = set_bit ( i, sizeof i * CHAR_BIT, 1 );
printf ( "i too big: %d\n", i );
i = 0;
i = set_bit ( i, -1, 1 );
printf ( "i too small: %d\n", i );
return 0;
}
It's still probably confusing, but better than it would be if you hard coded ( 1UL << i ) everywhere.