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
.
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.
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.
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).
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:
std::byte
ObjectsBitwise 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
std::byte
and Integer TypesWhen 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:
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.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};
}
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 IntegersWhile 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.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.
Learn how C++ represents numbers and data in memory using binary, decimal, and hexadecimal systems.