Numeric and Binary Data

Bitwise Operations

How can I perform bitwise operations like AND or OR on variables storing binary data?

Abstract art representing computer programming

To perform bitwise operations on binary data, you'll typically use unsigned integer types like uint8_t, uint16_t, or uint32_t. These types allow you to directly manipulate individual bits using operators like & (AND), | (OR), ^ (XOR), and ~ (NOT).

Let's say you have two bytes of data represented as uint8_t variables, and you want to perform a bitwise AND operation:

#include <cstdint>
#include <iostream>
#include <format>

int main() {
  uint8_t Byte1{0b11001100};
  uint8_t Byte2{0b10101010};

  // Bitwise AND
  uint8_t Result = Byte1 & Byte2;

  std::cout << std::format("{:b}", Result);
}
10001000

In this example, Result will hold the value 0b10001000. Each bit in Result is set to 1 only if the corresponding bits in both Byte1 and Byte2 are 1.

Bitwise OR

Similarly, for a bitwise OR, you can use the | operator:

#include <cstdint>
#include <iostream>
#include <format>

int main() {
  uint8_t Byte1{0b11001100};
  uint8_t Byte2{0b10101010};

  uint8_t Result = Byte1 | Byte2;  // Bitwise OR

  std::cout << std::format("{:b}", Result);
}
11101110

Here, Result will be 0b11101110. A bit in Result is set to 1 if either of the corresponding bits in Byte1 or Byte2 is 1.

Bitwise XOR

For a bitwise XOR (exclusive OR), use the ^ operator:

#include <cstdint>
#include <iostream>
#include <format>

int main() {
  uint8_t Byte1{0b11001100};
  uint8_t Byte2{0b00101010};

  // Bitwise XOR
  uint8_t Result = Byte1 ^ Byte2;

  std::cout << std::format("{:b}", Result);
}
11100110

In this case, Result will be 0b11100110. A bit in Result is set to 1 if the corresponding bits in Byte1 and Byte2 are different.

Bitwise NOT

Finally, the bitwise NOT operator ~ inverts the bits of a single operand:

#include <cstdint>
#include <iostream>
#include <format>

int main() {
  uint8_t Byte1{0b01001100};

  uint8_t Result = ~Byte1;  // Bitwise NOT

  std::cout << std::format("{:b}", Result);
}
10110011

Here, Result will be 0b00110011. Each bit in Byte1 is flipped (0 becomes 1, and 1 becomes 0).

Working With std::byte

std::byte is designed to represent a raw byte of data, and it does support bitwise operations. However, there are some nuances to be aware of:

Operations Between Two std::byte Objects

Bitwise operations are directly supported between two std::byte objects. The result of such operations is another std::byte.

#include <cstddef>
#include <iostream>

int main() {
  std::byte Byte1{0b11001100};
  std::byte Byte2{0b10101010};

  std::byte ResultAnd{Byte1 & Byte2}; // Bitwise AND
  std::byte ResultOr{Byte1 | Byte2};  // Bitwise OR
  std::byte ResultXor{Byte1 ^ Byte2}; // Bitwise XOR
  std::byte ResultNot{~Byte1};        // Bitwise NOT

  std::cout << "Result AND: "
    << std::to_integer<int>(ResultAnd) << "\n";
  std::cout << "Result OR: "
    << std::to_integer<int>(ResultOr) << "\n";
  std::cout << "Result XOR: "
    << std::to_integer<int>(ResultXor) << "\n";
  std::cout << "Result NOT: "
    << std::to_integer<int>(ResultNot) << "\n";
}
Result AND: 136
Result OR: 238
Result XOR: 102
Result NOT: 51

Operations Between std::byte and Integer Types

When you perform bitwise operations between a std::byte and an integer type (like int or uint8_t), the result is always a std::byte. The result of these operations is as follows:

  • For operator&, operator|, operator^, operator&=, operator|=, and operator^=, an integral type is not supported as the right operand, but we can convert it to a std::byte in advance.
  • For operator~, operator<<, operator>>, operator<<=, and operator>>=, the integer operand is treated as a count of bits, and the std::byte is shifted accordingly.
#include <cstddef>

int main() {
  std::byte MyByte{0b00001111};

  // Bit shifting a byte uses an integer
  MyByte <<= 2;

  // This won't work
  MyByte &= 0b11110000;  

  // But we can do this
  MyByte &= std::byte{0b11110000};
}

Casting with std::byte

The main purpose of std::byte is to indicate that you're working with raw data rather than arithmetic values.

However, if you need to perform arithmetic operations or use std::byte in contexts where an integer is expected, you can use std::to_integer:

#include <cstddef>
#include <iostream>

int main() {
  std::byte MyByte{42};

  // Convert std::byte to an integer
  int MyInt{std::to_integer<int>(MyByte)};

  std::cout << "MyInt: " << MyInt << "\n";
}
MyInt: 42

std::byte vs Unsigned Integers

While both std::byte and unsigned integers can represent raw bytes of data, their intended use cases are different:

  • std::byte: Primarily for representing raw data where arithmetic operations are not meaningful. Bitwise operations are supported between two std::byte objects or between a std::byte and an integer.
  • Unsigned Integers (e.g., uint8_t): Suitable for both raw data representation and numerical calculations. They support a wider range of operations, including arithmetic.

In summary, std::byte does support bitwise operations directly, and you don't need to cast to unsigned integers when working with two std::byte objects.

However, when mixing with integers or performing arithmetic, understanding the implicit conversions and using std::to_integer when needed is important.

The choice between std::byte and unsigned integers depends on whether you want to emphasize the raw data aspect or need numerical operations.

Answers to questions are automatically generated and may not have been reviewed.

sdl2-promo.jpg
Part of the course:

Game Dev with SDL2

Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games

Free, unlimited access

This course includes:

  • 79 Lessons
  • 100+ Code Samples
  • 91% Positive Reviews
  • Regularly Updated
  • Help and FAQ
Free, Unlimited Access

Professional C++

Comprehensive course covering advanced concepts, and how to use them on large-scale projects.

Screenshot from Warhammer: Total War
Screenshot from Tomb Raider
Screenshot from Jedi: Fallen Order
Contact|Privacy Policy|Terms of Use
Copyright © 2025 - All Rights Reserved