How to Compare Bits in C

Jinku Hu Feb 02, 2024
  1. Implement a Custom Function Using Bitwise XOR and AND Operations for Bit Comparison in C
  2. Use Bitwise OR (|) Operator for Bit Comparison in C
  3. Use Bitwise NOT (~) Operator for Bit Comparison in C
  4. Conclusion
How to Compare Bits in C

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 0s into 1s and 1s into 0s.

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.

Author: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

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