How to create a byte out of 8 bool values (and vice versa)?
The hard way:
unsigned char ToByte(bool b[8])
{
unsigned char c = 0;
for (int i=0; i < 8; ++i)
if (b[i])
c |= 1 << i;
return c;
}
And:
void FromByte(unsigned char c, bool b[8])
{
for (int i=0; i < 8; ++i)
b[i] = (c & (1<<i)) != 0;
}
Or the cool way:
struct Bits
{
unsigned b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
};
union CBits
{
Bits bits;
unsigned char byte;
};
Then you can assign to one member of the union and read from another. But note that the order of the bits in Bits
is implementation defined.
Note that reading one union member after writing another is well-defined in ISO C99, and as an extension in several major C++ implementations (including MSVC and GNU-compatible C++ compilers), but is Undefined Behaviour in ISO C++. memcpy
or C++20 std::bit_cast
are the safe ways to type-pun in portable C++.
(Also, the bit-order of bitfields within a char
is implementation defined, as is possible padding between bitfield members.)
Python - making and int from 8 boolean byte values and vice versa
import math
def bools_to_int(bits):
value = 0
for i, bit in enumerate(bits):
value |= bit << (len(bits) - i - 1)
return value
def int_to_bools(value):
bits = []
n = math.ceil(math.log2(value))
for i in range(n):
bits.append(value >> (n - i - 1) & 1 == 1)
return bits
print(bools_to_int([False, True, True, True, True, False, True, True]))
# Outputs 123
print(int_to_bools(123))
# Outputs [True, True, True, True, False, True, True]
You can also add a padding parameter to int_to_bools
if you want the leading digits:
def int_to_bools(value, pad=-1):
bits = []
n = max(pad, math.ceil(math.log2(value)))
for i in range(n):
bits.append(value >> (n - i - 1) & 1 == 1)
return bits
print(int_to_bools(123, pad=8))
# Outputs [False, True, True, True, True, False, True, True]
You can also add a endian parameter to both functions if you want to control how the bits are parsed:
import math
def bools_to_int(bits, big_endian=True):
value = 0
for i, bit in enumerate(bits):
shift = (len(bits) - i - 1) if big_endian else i
value |= bit << shift
return value
def int_to_bools(value, pad=-1, big_endian=True):
bits = []
n = max(pad, math.ceil(math.log2(value)))
for i in range(n):
shift = (n - i - 1) if big_endian else i
bits.append(value >> shift & 1 == 1)
return bits
print(bools_to_int([False, True, True, True, True, False, True, True], big_endian=True))
# Outputs 123, parse as 01111011
print(bools_to_int([False, True, True, True, True, False, True, True], big_endian=False))
# Outputs 222, parse as 11011110
Correct way to convert 8 bools into 1 byte
You probabbly searching for BitArray Constructor (Boolean[])
For rapresenting bits you have special structure BitArray
in C#
.
So your code would look like this:
var booleans = new bool[]{true, false, false, false};
var bitArray = new BitArray(booleans);
How can I go from a bit array to an byte?
You could use bit shifting in order to get the char from the bit array like so:
int bits[8] = { 0, 1, 1, 0, 0, 1, 0, 1 };
char result = 0; // store the result
for(int i = 0; i < 8; i++){
result += (bits[i] << (7 - i)); // Add the bit shifted value
}
cout << result;
This basically loops through your array, bitshifts by the correct amount, and then adds the value to an aggregating "result" variable. The output should be "e".
byte[] to bool[] to use as flags and viceversa
A .NET bool "wastes" seven bits. So there is no direct way to go from a byte to eight booleans.
You could use the BitArray class, see Converting C# byte to BitArray.
So something like this:
var bytes = File.ReadAllBytes(filename);
var bitArray = new BitArray(bytes);
bool ninthBit = bitArray[8];
how to convert bool array in one byte and later convert back in bool array
Here's how I would implement this.
To convert the bool[]
to a byte
:
private static byte ConvertBoolArrayToByte(bool[] source)
{
byte result = 0;
// This assumes the array never contains more than 8 elements!
int index = 8 - source.Length;
// Loop through the array
foreach (bool b in source)
{
// if the element is 'true' set the bit at that position
if (b)
result |= (byte)(1 << (7 - index));
index++;
}
return result;
}
To convert a byte to an array of bools with length 8:
private static bool[] ConvertByteToBoolArray(byte b)
{
// prepare the return result
bool[] result = new bool[8];
// check each bit in the byte. if 1 set to true, if 0 set to false
for (int i = 0; i < 8; i++)
result[i] = (b & (1 << i)) != 0;
// reverse the array
Array.Reverse(result);
return result;
}
Checking if a bit is set or not
sounds a bit like homework, but:
bool IsBitSet(byte b, int pos)
{
return (b & (1 << pos)) != 0;
}
pos 0 is least significant bit, pos 7 is most.
Related Topics
What Is the Windows Equivalent For En_Us.Utf-8 Locale
Is This Behavior of Vector::Resize(Size_Type N) Under C++11 and Boost.Container Correct
Why Does Const Imply Internal Linkage in C++, When It Doesn't in C
Is Main() Really Start of a C++ Program
How to Open an Std::Fstream (Ofstream or Ifstream) With a Unicode Filename
How to Forward Declare an Inner Class
How to Convert a Double into a String in C++
How to Implement Atoi Using Simd
How to Create a Thread Pool Using Boost in C++
What Variable Type For Extremely Big Integer Numbers
Benefits of Initialization Lists
Using Char* as a Key in Std::Map
C++ Pass an Array by Reference
Why Does This Function Push Rax to the Stack as the First Operation