Home | Projects | Notes > C Programming > Bitwise Operators
&
(Bitwise AND)
|
(Bitwise OR)
~
(Bitwise NOT - Negation) Unary
^
(Bitwise XOR) - Bitwise addition without carry
>>
(Bitwise Right Shift)
<<
(Bitwise Left Shift)
&&
is a logical AND operator
&
is a bitwise AND operator
Example:
xxxxxxxxxx
301char A = 40;
2char B = 30;
3char C;
4
5// Logical AND vs. bitwise AND
6C = A && B; // C contains 1 (meaning true)
7C = A & B; // C contains '00001000(2)' which is 8
8 // A 00101000
9 // B 00011110
10 // -----------
11 // C 00001000
12
13// Logical OR vs. Bitwise OR
14C = A || B; // C contains 1 (meaning true)
15C = A | B; // C contains '00111110(2)' which is 62
16 // A 00101000
17 // B 00011110
18 // -----------
19 // C 00111110
20
21// Logical NOT vs. Bitwise NOT
22C = !A; // C contains '0' (meaning false)
23C = ~A; // C contains '11010111(2)' which is -41
24
25// Bitwise XOR
26C = A ^ B // C contains '00110110(2)'
27 // A 00101000
28 // B 00011110
29 // -----------
30 // C 00110110
In embedded C programs, most of the time you will be doing:
Testing of bits (&
)
Testing bits to analyze the status register of a peripheral
Setting of bits (|
)
e.g., Setting bits to turn on LED
Clearing of bits (~
and &
)
e.g., Clearing bits to turn off LED
Toggling of bits (^
)
Write a program which takes 2 integers from the user, computes bitwise &
, |
,^
and ~
and prints the result.
xxxxxxxxxx
161
2
3int main(int argc, char *argv[])
4{
5 int n1, n2;
6
7 printf("Enter two integers: ");
8 scanf("%d %d", &n1, &n2);
9
10 printf("%d & %d = %d\n", n1, n2, n1 & n2);
11 printf("%d | %d = %d\n", n1, n2, n1 | n2);
12 printf("%d ^ %d = %d\n", n1, n2, n1 ^ n2);
13 printf("~%d = %d, ~%d = %d\n", n1, ~n1, n2, ~n2);
14
15 return 0;
16}
xxxxxxxxxx
51Enter two integers: 1 2
21 & 2 = 0
31 | 2 = 3
41 ^ 2 = 3
5~1 = -2, ~2 = -3
Write a program to find out whether a use entered integer is even or odd. Print an appropriate message on the console. Use testing of bits logic.
xxxxxxxxxx
161
2
3int main(int argc, char *argv[])
4{
5 int n;
6
7 printf("Enter an integer: ");
8 scanf("%d", &n);
9
10 if (n & 1) // here 1 is the mask value
11 printf("%d is an odd number.\n", n);
12 else
13 printf("%d is an even number.\n", n);
14
15 return 0;
16}
xxxxxxxxxx
21Enter an integer: 42
242 is an odd number.
Bit masking is a technique in programming used to test or modify the states of the bits of a given data.
Modify : If the state of the bit is zero make it one, or if the state of the bit is 1 then make it 0.
Test: Check whether the required bit position of a data is 0 or 1.
Write a program to set(make bit state to 1) 4th and 7th bit position of a given number and print the result.
xxxxxxxxxx
121
2
3int main(int argc, char *argv[])
4{
5 int n = 0x0;
6
7 n |= (1 << 4); // set 4th bit position to 1
8 n |= (1 << 7); // set 7th bit position to 1
9 printf("%d\n", n); // 10010000(2) or 144
10
11 return 0;
12}
xxxxxxxxxx
11144
Could've done n |= 0x90;
instead.
Write a program to clear(make bit state to 0) 4th, 5th, 6th bit positions of a given number and print the result.
xxxxxxxxxx
131
2
3int main(int argc, char *argv[])
4{
5 int n = 0xFF;
6
7 n &= ~(1 << 4); // clear 4th bit position
8 n &= ~(1 << 5); // clear 5th bit position
9 n &= ~(1 << 6); // clear 6th bit position
10 printf("%d\n", n); // 10001111(2) or 143
11
12 return 0;
13}
xxxxxxxxxx
11143
Alternative 2 ways:
xxxxxxxxxx
11 n &= 0x8F; // using 10001111(2)
Directly perform bitwise AND
You need to think and calculate the mask value.
xxxxxxxxxx
11 n &= ~(7 << 4); // using 01110000(2)
Negate the mask value first and then perform bitwise AND
This method could be a shortcut since it it easier to identify the bit pattern to clear and shift it to the proper position. In this case, 111(2) is 7 and we just need to shift 7 to the right 4 places.
Rewrite the following code snippet using toggling of bits.
xxxxxxxxxx
71while (1)
2{
3 if (LED == 0)
4 LED == 1;
5 else
6 LED == 0;
7}
Using bitwise XOR operator ^
, above code can be rewritten as:
xxxxxxxxxx
21while (1)
2 LED ^= 0x01;
Bits of the 1st operand will be right (>>
) or left (<<
) shifted by the amount decided by the 2nd operand.
xxxxxxxxxx
31/* syntax */
2operand1 >> operand2 /* right shift */
3operand1 << operand2 /* left shift */
A value will be multiplied by 2 for each left shift.
A value will be divided by 2 for each right shift.
In an embedded C programs, bitwise shift operators are frequently used to bit-mask data along with other bitwise logic operators. Predominantly used while setting or clearing bits. (See Use Case: Setting of Bits, and Use Case: Clearing of Bits section above)
Extract bit positions from 9th to 14th [14:9] in a given data and save it in to another variable:
Shift the identified portion to right hand side until it touches the least significant bit (0th bit).
Mask the value to extract only 6 bits [5:0] and then save it in to another variable.
xxxxxxxxxx
21uint16_t data = 0xB410; /* given data */
2uint8_t output = (uint8_t)((data >> 9) & 0x003F);
Nayak, K. (2022). Microcontroller Embedded C Programming: Absolute Beginners [Video file]. Retrieved from https://www.udemy.com/course/microcontroller-embedded-c-programming/