How to Compare Bits in C
-
Implement a Custom Function Using Bitwise
XOR
andAND
Operations for Bit Comparison in C -
Use Bitwise
OR
(|
) Operator for Bit Comparison in C -
Use Bitwise
NOT
(~
) Operator for Bit Comparison in C - Conclusion
Bitwise operations are fundamental in computer programming, especially when working with low-level data manipulation. In C, there are several methods to compare individual bits or groups of bits.
In this article, we will explore different techniques along with code examples to demonstrate each method.
Implement a Custom Function Using Bitwise XOR
and AND
Operations for Bit Comparison in C
The bitwise AND
operator (&
) is used to perform a bitwise comparison between corresponding bits of two operands. This operation results in a new value where each bit is set if and only if the corresponding bits in both operands are set.
Example Code:
#include <stdio.h>
int main() {
unsigned int num1 = 9; // Binary representation: 1001
unsigned int num2 = 6; // Binary representation: 0110
unsigned int result = num1 & num2;
printf("Result: %u\n", result); // Output: 0 (Binary: 0000)
return 0;
}
Output:
Result: 0
In this example, num1
and num2
are initialized with values 9
and 6
, respectively. These values are represented in binary as 1001
and 0110
.
The bitwise AND
operation between num1
and num2
(num1 & num2
) results in 0000
in binary, which is 0
in decimal. This means that no corresponding bits are set in both num1
and num2
.
Meanwhile, the bitwise XOR
operator (^
) is used to perform a bitwise comparison between corresponding bits of two operands. This operation results in a new value where each bit is set if the corresponding bits in the operands are different.
Example Code:
#include <stdio.h>
int main() {
unsigned int num1 = 9; // Binary representation: 1001
unsigned int num2 = 6; // Binary representation: 0110
unsigned int result = num1 ^ num2;
printf("Result: %u\n", result); // Output: 9 (Binary: 1001)
return 0;
}
Output:
Result: 15
In this example, the bitwise XOR
operation (num1 ^ num2
) results in 1001
in binary, which is 9
in decimal. This means that the corresponding bits in num1
and num2
are different.
Generally, bit comparison entails accessing single-bit values and conducting needed operations, such as implementing bit-field using union
and struct
keywords.
However, bitwise operations offer a more efficient method of comparing specified bits in numbers. In this case, we implement a separate function suited for the u_int32_t
type, which is guaranteed to have a 32-bit width.
The example program below takes three integers as command-line arguments, the first two of which are the numbers that are compared, while the third integer specifies the n-th bit. Notice that we convert argv
elements using strtol
, thus losing some precision when storing the return values in the u_int32_t
type.
The compareBits
function declares two local variables storing intermediate values - mask
and tmp
. We set the n-th bit in the mask
by shifting the 1
left by nth - 1
positions.
Then, both user input numbers are XOR
-ed to get the bit differences in each position with a set bit in the result denoting different values. Finally, we need to extract the bit from the n-th position and check if the value is 0
.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
bool compareBits(u_int32_t n1, u_int32_t n2, u_int32_t nth) {
u_int32_t mask, tmp;
mask = 1 << (nth - 1);
tmp = n1 ^ n2;
if ((tmp & mask) == 0)
return true;
else
return false;
}
int main(int argc, char *argv[]) {
u_int32_t num1, num2, bit;
if (argc != 4) {
fprintf(stderr, "Usage: %s integer1 integer2 nth_bit \n", argv[0]);
exit(EXIT_FAILURE);
}
num1 = strtol(argv[1], NULL, 0);
num2 = strtol(argv[2], NULL, 0);
bit = strtol(argv[3], NULL, 0);
compareBits(num1, num2, bit) ? printf("bits equal!\n")
: printf("bits not equal!\n");
exit(EXIT_SUCCESS);
}
Sample File Format:
./main 1234 1231 1
Input File Format:
bits not equal!
As an example, the integers 1234
and 1231
are represented in binary as 00000000000000000000010011010010
and 00000000000000000000010011001111
, respectively.
Thus, XOR
-ing these two result in a 00000000000000000000000000011101
binary representation, which is finally AND
-ed with the mask 00000000000000000000000000000010
to extract the single-bit position value. If the result is all zeros, it implies that compared bits are equal; otherwise, it is the opposite.
Alternatively, though, we can shorten the compareBits
function and move the XOR
/AND
operations to the return
statement, as shown in the following example code. Note that the function returns the logical opposite of bitwise XOR
/AND
operations, as we output the corresponding messages in the caller function using the ? :
ternary statement.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
bool compareBits(u_int32_t n1, u_int32_t n2, u_int32_t nth) {
u_int32_t mask;
mask = 1 << (nth - 1);
return !((n1 ^ n2) & mask);
}
int main(int argc, char *argv[]) {
u_int32_t num1, num2, bit;
if (argc != 4) {
fprintf(stderr, "Usage: %s integer1 integer2 nth_bit \n", argv[0]);
exit(EXIT_FAILURE);
}
num1 = strtol(argv[1], NULL, 0);
num2 = strtol(argv[2], NULL, 0);
bit = strtol(argv[3], NULL, 0);
compareBits(num1, num2, bit) ? printf("bits equal!\n")
: printf("bits not equal!\n");
exit(EXIT_SUCCESS);
}
Sample File Format:
./main 1234 1231 2
Input File Format:
bits equal!
Use Bitwise OR
(|
) Operator for Bit Comparison in C
The bitwise OR
operator (|
) performs a bitwise comparison between corresponding bits of two operands. The result of this operation is a new value where each bit is set if at least one of the corresponding bits in either operand is set.
When applied to a pair of bits, the OR
operation follows this logic:
`0 | 0` |
`0 | 1` |
`1 | 0` |
`1 | 1` |
Consider the following example to illustrate the bitwise OR
operation:
#include <stdio.h>
int main() {
unsigned int num1 = 9; // Binary representation: 1001
unsigned int num2 = 6; // Binary representation: 0110
unsigned int result = num1 | num2;
printf("Result: %u\n", result); // Output: 15 (Binary: 1111)
return 0;
}
Output:
Result: 15
In this example, we have two unsigned integers, num1
and num2
initialized with values 9
and 6
, respectively. Their binary representations are 1001
and 0110
.
When we perform the bitwise OR
operation (num1 | num2
), the result is 1111
in binary, which is 15
in decimal. This means that at least one of the corresponding bits in either num1
or num2
is set.
Use Bitwise NOT
(~
) Operator for Bit Comparison in C
The bitwise NOT
operator (~
) is a unary operator, meaning it operates on a single operand. When applied to a binary number, it inverts each bit, turning 0
s into 1
s and 1
s into 0
s.
Example Code:
#include <stdio.h>
int main() {
unsigned int num = 9; // Binary representation: 1001
unsigned int result = ~num;
printf(
"Result: %u\n",
result); // Output: 4294967286 (Binary: 11111111111111111111111111111010)
return 0;
}
Output:
Result: 4294967286
In this example, we declare an unsigned integer variable num
and initialize it with the value 9
. In binary, this is represented as 1001
.
We then apply the bitwise NOT
operator (~num
). This inverts all the bits, resulting in 11111111111111111111111111111010
in binary.
The result is printed to the console, which is 4294967286
in decimal.
Bitwise NOT
for Comparing Bits
One of the applications of the bitwise NOT
operator is comparing bits. By inverting the bits of a variable, we can easily check if a particular bit is set or unset.
Example Code:
#include <stdio.h>
int main() {
unsigned int num = 9; // Binary representation: 1001
// Check if the 2nd bit is set
unsigned int mask = 1 << 1; // Shift 1 by 1 position to the left => 0002
unsigned int result = ~num & mask;
if (result == mask) {
printf("2nd bit is set.\n");
} else {
printf("2nd bit is not set.\n");
}
return 0;
}
Output:
2nd bit is set.
In this example, we want to check if the 2nd bit of the variable num
is set.
We first create a mask by shifting the 1 by 1 position to the left (1 << 1
), resulting in 0002
in binary. We then apply the bitwise NOT
operator to num
, resulting in 11111111111111111111111111111010
in binary.
Next, we perform a bitwise AND
operation between the inverted num
and the mask. This isolates the 2nd bit.
If the result is equal to the mask, it means the 2nd bit is set, and we print a corresponding message. Otherwise, we print a message indicating the 2nd bit is not set.
Conclusion
In this comprehensive exploration of bitwise operators in C, we’ve covered fundamental operations like AND
, OR
, and NOT
. These operations are invaluable for tasks involving low-level data manipulation, such as data compression, encryption, and embedded systems programming.
Specifically, we delved into the use of the bitwise NOT
(~
) operator for comparing individual bits. By applying the ~
operator, we can easily invert the bits of a variable, enabling us to check if a particular bit is set or unset. This technique is essential in scenarios where precise bit-level manipulation is required.
Understanding and mastering bitwise operations is crucial for programmers working on tasks that involve direct interaction with hardware or require optimized solutions for resource-constrained environments. With the knowledge gained from this article, you are now equipped to leverage these powerful tools in your own C programming projects.
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook