Bitwise Operations in C

  1. Bitwise & and &= Operators
  2. Bitwise | and |= Operators
  3. Bitwise ^ and ^= Operators
  4. Bitwise Shift (>>) and (<<) Operators
  5. Arithmetic ShortHands (Compound Assignment Statements)
  6. Lexical Analysis and What You Can’t Do

This article discusses bitwise operations (and operators) in C. These concepts extend to C++ as well.

In addition to these operators, the article discusses a commonly misunderstood operator assignment shorthand notation (such as the += operator assignment). We will discuss this in the context of bitwise operators.

The article will have an example of each of these operators showing both notations and their respective outputs. We will also discuss shorthand notations that are not supported by C.

Lastly, we will briefly discuss the lexical analysis, which is a stage in the compilation of the program where the compiler generates tokens. These are the smallest parts of the code, such as keywords, identifiers, constants, string literals, etc.

Bitwise & and &= Operators

& is the bitwise and operator. It is used like this:

int test = 0x6A;
test = test & 0x50;

The above code runs the bitwise and comparison between 0x6A and 0x50 and saves the result to the test variable. The bitwise and operation compares each bit of both arguments.

The result is 1 for each bit if both operands’ bits are 1, and the result is 0 otherwise.

The binary for 0x6A is 1101010, and the binary for 0x50 is 1010000. Therefore, the and operation result is 1000000.

Now we can discuss the shorthand notation. The above piece of code can conveniently be written as the following:

int test2 = 0x6A;
test2 &= 0x50;

In general, x &= 5 is equivalent to x = x & 5. However, this can be extended to other operations too; the most common would be +=, -=, *=, /=.

More uncommon examples of this shorthand notation are with bitwise operations such as >>=, <<=, |=, &=, ^=.

Bitwise | and |= Operators

| is the bitwise inclusive or operator.

int test = 0x6A;
test = test | 0x50;

The shorthand notation for this will be:

int test = 0x6A;
test |= 0x50;

The resulting value of test is 1111010.

The bitwise inclusive or operation compares each bit of both arguments. The result is 1 for each bit if either of the operands’ bits is 1, and the result is 0 only when both operands are 0.

Bitwise ^ and ^= Operators

^ is the bitwise exclusive or operator.

int test = 0x6A;
test = test ^ 0x50;

The shorthand notation for this will be:

int test = 0x6A;
test ^= 0x50;

The resulting value of test is: 0111010

The bitwise exclusive or operation compares each bit of both arguments. The resulting bit value is 1 for each bit of the result if the two bits have different values; it is 0 if both bits have the same value.

Bitwise Shift (>>) and (<<) Operators

The shift operators have two operands.

The shift is applied on the operand to the left. And the number of bits that the shift is applied is determined by the right operand.

There are two kinds of shifts: the left shift <<, and the right shift >>. It is generally used as follows:

Please see this linked document for more details about the result of the shift operator if you are unsure about its details.

int test5 = 0xFF;
test5 = test5 << 2;

In this example, the bits stored in test5 will be left-shifted (as indicated by the operator’s direction) by 2 bits.

Before shift: 0011111111
After shift:  1111111100

Similarly, for the right shift:

int test5 = 0xFF;
test5 = test5 >> 2;

In this example, the bits stored in test5 will be right-shifted by 2 bits.

Before shift: 11111111
After shift:  00111111

The shorthand notation for the right and left shifts is similar to what we have above.

Shorthand right shift notation:

int test5 = 0xFF;
test5 >>= 2;

Shorthand left shift notation:

int test5 = 0xFF;
test5 <<= 2;

Arithmetic ShortHands (Compound Assignment Statements)

This section will briefly discuss shorthands for arithmetic operations. The following two statements after the variable declaration are equivalent:

For addition:

int addTest = 5;

addTest += 5;

and

addTest = addTest + 5;

For multiplication:

int multTest = 5;

multTest *= 5;

and

multTest = multTest * 5;

For division:

int divTest = 5;

divTest /= 5;

and

divTest = divTest / 5;

For subtraction:

int subTest = 5;

subTest -= 5;

and

subTest = subTest - 5;

For modulo/remainder (%):

int remTest = 5;

remTest %= 5;

and

remTest = remTest % 5;

Lexical Analysis and What You Can’t Do

Lexical analysis is a stage in which each operand and the operator are separated into tokens. For example, in a statement x + 2, where x is a variable, the analyzer will separate x and 2 as operands and + as the operator.

For shorthand notation, operators such as |= are stored with a token code, which is enough to identify them. If any shorthands do not work, they (simply) have not been defined for the C lexical analyzer; even if they pass the lexical analyzer, the syntax analyzer will reject them.

This is why shorthands such as >>>> or ||= or &&= do not work. Perhaps there would be a programming language where they are accepted as valid operators.

Write for us
DelftStack articles are written by software geeks like you. If you also would like to contribute to DelftStack by writing paid articles, you can check the write for us page.