View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All

Bitwise Operators in C: Easy Guide with Truth Tables

Updated on 19/05/20253,117 Views

While debugging C programs, it’s common to face challenges related to performance, memory, or low-level data processing. In such cases, using Bitwise Operators in C often brings surprising benefits. They let you manipulate data at the binary level, offering speed and control where traditional operators fall short.

When writing systems software, device drivers, or embedded code, every byte and bit counts. Bitwise Operators in C empower programmers to perform operations that directly interface with hardware or optimize performance in critical sections. Their compactness and speed make them essential in certain domains of C programming. 

Pursue our Software Engineering courses to get hands-on experience!

What Are Bitwise Operators in C?

Bitwise operators perform operations on the individual bits of integers. These operators treat data as sequences of 0s and 1s. Understanding how to convert decimal numbers to binary is essential when working with bitwise operators in C. They are mostly used with int, char, short, or long types. The result is a new value computed bit by bit, following a predefined logic.

Syntax of Bitwise Operators in C

result = operand1 <bitwise_operator> operand2;

Here’s a basic usage example:

#include <stdio.h>
int main() {
    int a = 5;      // Binary: 0101
    int b = 3;      // Binary: 0011
    int result = a & b;
    printf("Result = %d\n", result);
    return 0;
}

Output:

Result = 1

Explanation:The binary AND of 0101 and 0011 is 0001, which is 1 in decimal. The & operator compares each bit and returns 1 only if both bits are 1.

Take your skills to the next level with these top programs:

What Are the Different Types of Bitwise Operators in C?

C provides six types of bitwise operators. Each performs a unique binary operation on corresponding bits of the operands. These include:

Bitwise AND Operator in C (&)

This operator performs a logical AND operation on each pair of corresponding bits.Truth Table:

A

B

A & B

0

0

0

0

1

0

1

0

0

1

1

1

Example:

#include <stdio.h>
int main() {
    int x = 6;   // Binary: 0110
    int y = 4;   // Binary: 0100
    int res = x & y;
    printf("Bitwise AND = %d\n", res);
    return 0;
}

Output:

Bitwise AND = 4

Explanation: Only the second-highest bit is common in both numbers. So, 0110 & 0100 = 0100, which is 4.

Bitwise OR Operator in C (|)

This operator returns 1 if at least one of the bits is 1.

Truth Table:

A

B

A | B

0

0

0

0

1

1

1

0

1

1

1

1

Example:

#include <stdio.h>
int main() {
    int x = 5;   // Binary: 0101
    int y = 3;   // Binary: 0011
    int res = x | y;
    printf("Bitwise OR = %d\n", res);
    return 0;
}

Output:

Bitwise OR = 7

Explanation: 0101 | 0011 = 0111. The result is 7 in decimal.

Bitwise XOR Operator in C (^)

The XOR operator returns 1 only if the bits are different.

Truth Table:

A

B

A ^ B

0

0

0

0

1

1

1

0

1

1

1

0

Example:

#include <stdio.h>
int main() {
    int a = 9;    // Binary: 1001
    int b = 5;    // Binary: 0101
    int result = a ^ b;
    printf("Bitwise XOR = %d\n", result);
    return 0;
}

Output:

Bitwise XOR = 12

Explanation: 1001 ^ 0101 = 1100, which is 12 in decimal. XOR is often used for toggling bits.

Must Read: XOR in Python article!

Bitwise NOT Operator in C (~)

This is a unary operator. It inverts all bits of the operand.

Truth Table:

A

~A

0

1

1

0

Example:

#include <stdio.h>
int main() {
    int x = 8;     // Binary: 00001000
    int res = ~x;
    printf("Bitwise NOT = %d\n", res);
    return 0;
}

Output:

Bitwise NOT = -9

Explanation: The NOT operator flips each bit. In signed integer representation (2's complement), ~8 becomes -9.

Bitwise Left Shift Operator in C (<<)

This operator shifts all bits to the left by a specified number of positions.

Truth Table for 1-bit Left Shift:

Input

Shift

Result

1

<<1

10

10

<<1

100

100

<<2

0001 0000

Example:

#include <stdio.h>
int main() {
    int num = 2;         // Binary: 0010
    int shifted = num << 2;
    printf("Left Shift = %d\n", shifted);
    return 0;
}

Output:

Left Shift = 8

Explanation: Shifting 0010 two positions left gives 1000, which equals 8.

Bitwise Right Shift Operator in C (>>)

This shifts bits to the right. The vacant positions are filled based on the system.

Truth Table for 1-bit Right Shift:

Input

Shift

Result

1

>>1

0

100

>>1

10

1000

>>3

1

Example:

#include <stdio.h>
int main() {
    int num = 16;        // Binary: 00010000
    int result = num >> 2;
    printf("Right Shift = %d\n", result);
    return 0;
}

Output:

Right Shift = 4

Explanation: Shifting 00010000 two positions to the right gives 00000100, or 4 in decimal.

How to Use Bitwise Operators in C with Examples?

Bitwise operators in C are not limited to theory. They are used widely in writing optimized and hardware-near code. With the help of these operators, developers can manipulate bits directly. This section includes beginner to advanced examples to help you understand their practical use in real-world scenarios. We also provide the output and an explanation with each example.

Beginner-Level Example with Output and Explanation

Let's begin with a basic example. We'll check if a number is even or odd using the bitwise AND (&) operator.

#include <stdio.h>
int main() {
    int num = 11;
    if (num & 1)
        printf("%d is Odd\n", num);
    else
        printf("%d is Even\n", num);
    return 0;
}

Output:

11 is Odd

Explanation: In binary, 11 is 1011. The least significant bit (LSB) tells us if the number is even or odd.

  • If LSB = 1 ;- the number is odd.
  • If LSB = 0 ;- the number is even.

Here, num & 1 isolates the last bit. If the result is 1, it’s odd. This approach is faster than using modulus (%) for checking parity.

Intermediate-Level Example Using Shifts and Masks

Now let’s use bitwise shift (<<) and AND (&) together. We’ll check whether the 3rd bit (from the right, 0-indexed) is set.

#include <stdio.h>
int main() {
    int num = 42;        // Binary: 00101010
    int mask = 1 << 2;   // Shift 1 to the 3rd bit position => 00000100

    if (num & mask)
        printf("3rd bit is set in %d\n", num);
    else
        printf("3rd bit is not set in %d\n", num);
    
    return 0;
}

Output:

3rd bit is set in 42

Explanation: We shift 1 left by 2 positions, making the mask 00000100 (i.e., 4). Then we use num & mask. If the result is non-zero, it means the 3rd bit is 1. This method is useful for reading specific flags or status bits in low-level programming like microcontroller registers.

Advanced Example with Bitwise Logic in Conditions

Let’s simulate a permission system using XOR (^). Suppose we are managing read, write, and execute permissions using bits:

  • READ = 4 (0100)
  • WRITE = 2 (0010)
  • EXECUTE = 1 (0001)

We’ll use XOR to toggle a permission.

#include <stdio.h>
#define READ  0x4  // 0100
#define WRITE 0x2  // 0010
#define EXEC  0x1  // 0001

int main() {
    int permissions = 0x7; // All permissions active: 0111

    printf("Initial Permissions = %d\n", permissions);

    // Revoke write permission using XOR
    permissions ^= WRITE;
    printf("Permissions after toggling WRITE = %d\n", permissions);

    // Restore write permission
    permissions ^= WRITE;
    printf("Permissions after restoring WRITE = %d\n", permissions);

    return 0;
}

Output:

Initial Permissions = 7

Permissions after toggling WRITE = 5

Permissions after restoring WRITE = 7

Explanation: Initially, all bits are set (7 = 0111). Using XOR with WRITE (2 = 0010):

  • First XOR clears the write bit: 0111 ^ 0010 = 0101 (5)
  • Second XOR sets it back: 0101 ^ 0010 = 0111 (7)

This approach is widely used in access control systems, flag toggling, and embedded programming where performance and precision matter.

What Are the Advantages of Bitwise Operators in C?

Bitwise operators in C offer a wide range of advantages, especially in performance-critical applications. They are an essential tool when working close to the hardware or when memory and speed are important constraints.

1. Extremely Fast Execution

Bitwise operations execute much faster than arithmetic or logical operations. They operate directly at the binary level, which means no conversion or extra CPU cycles are needed. In time-sensitive systems like embedded devices or game engines, this speed difference matters.

2. Efficient Use of Memory

Since each bit can represent a unique flag or state, developers can store multiple pieces of information in a single byte or integer. This is useful in resource-limited systems like microcontrollers. You can store 8 flags in one char, and 32 flags in one int.

Also explore the Difference Between Microcontroller and Microprocessor article!

3. Useful for Flag Management

You can use individual bits to represent flags. Bitwise AND (&), OR (|), and XOR (^) make it easy to set, clear, or toggle those flags. This method simplifies permission handling, status tracking, and control registers.

4. Widely Used in Embedded and Low-Level Programming

Bitwise operations are used to manipulate I/O ports, control bits in registers, and interact with memory-mapped hardware. Their directness and speed make them ideal for such low-level tasks.

5. Compact Code for Specific Tasks

Instead of writing multiple if-else conditions or switch blocks, bitwise logic can compactly represent logic for masks, toggles, and state checks. This results in smaller, cleaner, and faster code.

6. Used in Algorithms and Optimization

Bitwise operators are core to many advanced algorithms:

  • Swapping two numbers without using a temporary variable
  • Fast multiplication or division using shifts
  • Counting set bits or parity checks

These techniques are used in cryptography, graphics, networking, and compilers.

7. Avoid Overflow Issues in Certain Scenarios

Bitwise operations don’t involve carry or sign bits like arithmetic operations. So in some cases, especially with unsigned values, you can prevent overflow or undefined behavior.

What Are the Limitations of Bitwise Operators in C?

While bitwise operators in C are powerful, they come with several drawbacks that can lead to issues if not used carefully. Their low-level nature often introduces complexity and reduces code clarity.

1. Harder to Understand and Debug

Bitwise operations are not intuitive, especially for beginners. Expressions like value & 0xF0 or flags ^ (1 << 3) are hard to interpret without binary knowledge. Debugging such code becomes difficult without step-by-step tracing.

2. Code Readability Suffers

Unlike arithmetic or logical expressions, bitwise expressions don't convey intent clearly. For example, x = x & ~0x08 clears the fourth bit, but to most readers, the purpose is unclear. This lack of readability increases the maintenance burden.

3. Error-Prone for Large Data Manipulations

Manipulating multiple bits increases the chances of errors. Off-by-one shifts, incorrect masking, or wrong precedence can introduce bugs. These bugs are often silent and don't trigger compile-time warnings.

4. Non-Portable in Some Cases

Different systems might have different endianness or integer sizes. Bit-level manipulations relying on layout or specific memory patterns can behave unexpectedly across platforms. This affects portability, especially in embedded or cross-platform projects.

5. Limited to Integral Types

Bitwise operators only work with integers. They cannot be applied to float, double, or complex structures. This restricts their use in mathematical, scientific, or high-level data manipulation tasks.

6. Not Compiler-Safe with Signed Integers

Shifting signed integers, especially with right shift (>>), can result in implementation-defined behavior. In some systems, it performs arithmetic shift; in others, logical. This inconsistency can lead to incorrect results or bugs.

7. Requires Manual Bitmask Management

Creating and maintaining bitmasks manually increases code complexity. Using 1 << n or hexadecimal masks like 0x1F requires care and discipline. A single mistake can alter program logic drastically.

Common Mistakes While Using Bitwise Operators in C

Bitwise operators are efficient but easy to misuse. Knowing operator precedence and associativity is crucial for correctly evaluating complex bitwise expressions. Developers often make subtle mistakes that lead to incorrect results or hard-to-trace bugs. Let’s explore the most common pitfalls when working with bitwise operators in C.

1. Using Bitwise Operators Instead of Logical Ones

Beginners often confuse & with && or | with ||. While both operate on similar-looking symbols, their behaviors are entirely different.

Incorrect Code:

int a = 5, b = 10;
if (a & b) {
    printf("True\n");
}

Output:

True

Explanation: This doesn’t check if both a and b are non-zero. Instead, it performs a bitwise AND. The result is 0 only if no bits match. To check logical conditions, use &&.

2. Ignoring Operator Precedence

Bitwise operators have lower precedence than arithmetic or comparison operators. Without parentheses, expressions may not evaluate as expected.

Incorrect Code:

if (x & 1 == 0)

Output: May give unexpected results.

Explanation: Here, 1 == 0 evaluates first (resulting in false, i.e., 0), then x & 0 is checked. Use parentheses: if ((x & 1) == 0) to test for even numbers.

3. Shifting by Negative or Oversized Values

Right or left shifting a value by a negative number or by a shift amount ≥ bit-width leads to undefined behavior.

Example:

int x = 1;
x = x << 32;

Output: Undefined behavior (varies by compiler/system).

Explanation: On a 32-bit system, shifting by 32 or more is invalid. Always ensure the shift value is within valid range.

4. Using Bitwise NOT on Unsigned Data Improperly

The ~ operator inverts every bit. When applied to unsigned types, it can produce large, unexpected values.

Example:

unsigned int a = 5;
printf("%u", ~a);

Output: 4294967290 (on a 32-bit system)

Explanation: ~5 becomes 0xFFFFFFFA. Be cautious when using ~ with unsigned types, especially in comparisons.

5. Forgetting to Use Proper Bitmasking

When working with flags, developers sometimes forget to mask bits correctly before comparison or toggling.

Incorrect Code:

if (flags == 0x04)

Explanation: This checks if flags equals 0x04, not whether the third bit is set. Correct way:

if (flags & 0x04)

6. Misusing Compound Bitwise Assignments

Operators like |=, &=, ^=, or <<= can introduce bugs if the logic isn’t understood fully.

Example:

int mask = 0x01;
flags |= mask;
flags &= ~mask;

Explanation: The first sets the bit, the second clears it. If you confuse |= with &=, you’ll unintentionally toggle or unset the bit.

7. Overcomplicating Simple Logic

Bitwise logic is elegant when used properly but can make simple logic unnecessarily complex.

Example:

if ((val & 0x01) && !(val & 0x02))

Explanation: This is harder to read than a descriptive approach using named masks or boolean flags. Prefer meaningful variable names and constants to improve clarity.

Conclusion

Bitwise operators in C provide low-level control over data, making them powerful tools in a programmer’s toolkit. When used correctly, they allow for highly efficient and optimized code, especially in system programming, embedded development, and bit manipulation tasks.

Understanding and practicing bitwise operations not only enhances your problem-solving skills but also deepens your grasp of how computers process data at the bit level. Just remember to be cautious with precedence, signed shifts, and operator confusion.

Bitwise operators in C may seem intimidating at first, but with the right knowledge and practice, they become reliable allies in writing clean and efficient code.

FAQs

1. What are real-world applications of bitwise operators in C?

Bitwise operators are used in embedded systems, encryption algorithms, device drivers, graphics programming, and error detection. They help control hardware, manage flags, and optimize memory and performance in resource-constrained environments.

2. How are bitwise operators in C different from logical operators?

Bitwise operators manipulate individual bits within variables, whereas logical operators evaluate entire expressions as true or false. Bitwise operators return integers, while logical ones return either 0 (false) or 1 (true) after evaluating conditions.

3. Where are bitwise operators commonly used in embedded systems?

In embedded systems, bitwise operators are used to read or modify hardware register values, set or clear specific bits, manage control flags, and optimize performance in low-memory or real-time applications.

4. Can bitwise operators be used with floating-point values in C?

No, bitwise operators in C only work with integral types such as int, char, or long. They cannot be directly applied to float or double variables without typecasting or using memory manipulation techniques.

5. What is bit masking in C and how is it useful?

Bit masking involves using bitwise operators with specific bit patterns to isolate, set, or clear certain bits. It’s especially useful for flag operations, configuration settings, and hardware interaction in system-level programming.

6. Why should I use bitwise AND to check specific bits?

Bitwise AND (&) helps check if a specific bit is set by masking other bits. If the result is non-zero, the targeted bit is set. It’s a fast and reliable method used in flag checking.

7. Is there a difference between << and >> operators in C?

Yes. << performs a left shift, effectively multiplying the value by powers of 2. >> performs a right shift, dividing the value by powers of 2 and preserving or discarding sign bits depending on data type.

8. What happens if I shift bits too far in C?

Shifting a value by a negative number or a value equal to or greater than the variable’s bit width results in undefined behavior. Always ensure the shift amount is within a valid range for safe operation.

9. Can bitwise operators improve program performance?

Yes, bitwise operations are often faster than arithmetic or logical operations. They work directly at the hardware level, which helps optimize performance, especially in time-critical or low-level code like drivers or firmware.

10. Are bitwise operations portable across platforms in C?

Most bitwise operations are portable. However, signed right shifts and system endianness may cause differences. To ensure portability, avoid shifting signed integers and always test behavior on target platforms.

11. What is the use of XOR in programming logic?

The XOR operator (^) is commonly used for toggling bits, implementing bit-level encryption, or finding unique elements in arrays. It returns 1 only when the bits differ, making it useful for comparison logic.

12. How can I set and clear specific bits using bitwise operators?

To set a bit, use OR with a mask (val | mask). To clear a bit, use AND with the inverse of the mask (val & ~mask). These methods help manipulate flags efficiently in memory.

13. Why is bitwise NOT operator (~) risky with unsigned integers?

Using ~ on unsigned integers flips all bits, potentially producing large values due to the lack of sign extension. It’s important to apply it cautiously, especially in conditions or range checks.

14. How do I toggle a bit using bitwise operators?

You can toggle a bit using the XOR operator. For example, value ^= mask; flips the targeted bit without affecting others. It’s a simple and fast method to alternate flag states.

15. Can bitwise operators help in cryptography or security algorithms?

Yes. Bitwise operations like XOR, AND, and shifts are core components in many encryption and hashing algorithms. They enable fast, low-level data manipulation essential for cryptographic transformations.

image

Take a Free C Programming Quiz

Answer quick questions and assess your C programming knowledge

right-top-arrow
image
Join 10M+ Learners & Transform Your Career
Learn on a personalised AI-powered platform that offers best-in-class content, live sessions & mentorship from leading industry experts.
advertise-arrow

Free Courses

Start Learning For Free

Explore Our Free Software Tutorials and Elevate your Career.

upGrad Learner Support

Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)

text

Indian Nationals

1800 210 2020

text

Foreign Nationals

+918068792934

Disclaimer

1.The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.

2.The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not provide any a.