Basics of Bit Manipulation for C Programming

By Dan Gookin

A smattering of C programming operators provide data manipulation at the binary level. The operators are easy to ignore, but only when their true power and usefulness aren’t appreciated.

The ~ and ! operators

Two infrequent binary operators are the ~ (or 1’s complement) and the ! (or NOT). They lack the charm of the logical bitwise operators, but they have a place.

The 1’s complement operator flips all the bits in a value, turning a 1 into a 0 and a 0 into a 1. For example:

~01010011 = 10101100

The ! (NOT) operator affects the entire value — all the bits. It changes any nonzero value to 0, and the value 0 to 1:

!01010011 = 00000000
!00000000 = 00000001

Zero and 1 are the only two results possible when using the bitwise ! operator.

Both the ~ and ! operators are unary operators — you simply prefix a value to get the results.

Operator Name Type Action
& AND Bitwise Masks bits, resetting some bits to 0 and leaving the rest
alone
| OR Bitwise Sets bits, changing specific bits from 0 to 1
^ XOR Bitwise Changes bits to 0 when they match; otherwise, to 1
~ 1’s complement Unary Reverses all bits
~ NOT Unary Changes nonzero values to 0; 0 values, to 1
The binbin() function

Two statements explain what’s going on in the binbin() function to make it convert values into a binary string:

bin[x] = n & 0x80 ? '1' : '0';
n <<= 1;

The first statement performs an AND mask with the value n. All but the leftmost bit in the number is discarded. If that bit is set, which makes it a TRUE condition, the character 1 is stored in the array; otherwise, the character 0 is stored.

The value is expressed as 0x80, which is hexadecimal notation, a type of shorthand for binary. The hex value 0x80 is equal to 10000000 binary, which is the AND mask. If the value is 16 bits instead of 8, 0x8000 is used instead, which creates a 16-bit binary mask.

The second statement shifts the bits in the value n one notch to the left. As the loop spins, working through the value n, another bit in the value is shifted to the leftmost position. That bit is evaluated, and the binary string is built by inserting a ‘1’ or ‘0’ character.