问题
If I have an unsigned integer between 0 - 16 and I want to write it to a binary file without writing a whole byte to it, how would one shift bits to achieve it?
0-16 means I only need 4 bits, so I should be able to store 2 different numbers in a single byte right?
The following code writes 1 number to 1 byte:
std::ofstream file;
file.open("test.bin", std::ios::binary|std::ios::out);
char oneByteNum = (char)fourByteNum; // Converting from some 4 byte integer to a 1 byte char
file.write(&oneByteNum ,sizeof(char));
Using bitshifts, how can I achieve 2 numbers in 1 byte? I imagine reading the number out of the byte would be a similar, inverse 2 step process too?
回答1:
char oneByteWithTwoNums = (oneByteNum1 << 4) + (oneByteNum2 & 0x0f);
回答2:
Try this:
compacted = first_number * 0x10 + second-number;
To expand:
second_number = compacted & 0x0F;
first_number = compacted >> 4;
回答3:
I wrote up a quick example:
#include <iostream>
typedef unsigned char byte;
byte pack(unsigned int num1, unsigned int num2) {
// Our byte has the form 0b00000000
// We want the first four bits to be filled with num1
byte packed = num1 << 4;
// We want the last four bits to be filled with num2
// but, we don't want to overwrite the top four bits, so
// we mask it with 0x0F (0b0001111)
packed |= num2 & 0x0F;
return packed;
}
void unpack(byte b, unsigned int& num1, unsigned int& num2) {
// Extract the first four bits of our byte
num1 = b >> 4;
// Mask off the first four bits of our byte to get only
// the last four bits
num2 = b & 0x0F;
}
int main() {
unsigned int num1 = 5; // As an example
unsigned int num2 = 15; // As an example
byte b = pack(num1, num2);
unsigned int num3;
unsigned int num4;
unpack(b, num3, num4);
std::cout << num3 << std::endl;
std::cout << num4 << std::endl;
return 0;
}
You'll probably want to add checks in your pack/unpack methods to ensure someone doesn't try passing in a value other than [0-15].
来源:https://stackoverflow.com/questions/26516027/writing-4-bits-to-a-binary-file-with-ofstream