从 char 缓冲区中读取一位
Read a single bit from a buffer of char
我想实现这样的功能:
int read_single_bit(unsigned char* buffer, unsigned int index)
其中索引是我想要读取的位的偏移量。
如何使用位移或掩码来实现此目的?
您可能希望将其分成三个独立的任务:
- 正在确定哪个
char
包含您要查找的位。
- 正在确定您需要读取的
char
的位偏移量。
- 实际从
char
中选择那个位。
我将把第 (1) 和 (2) 部分留作练习,因为它们还不错。对于第 (3) 部分,您可能会发现有用的一个技巧是在所讨论的字节与您想要的索引处具有单个 1
位的字节之间执行按位与运算。例如,假设您想要从一个字节中取出第四位。然后你可以这样做:
Byte: 11011100
Mask: 00001000
----------------
AND: 00001000
因此请考虑以下问题:如果您知道位索引,您将如何生成所需的掩码?以及如何将 AND 结果转换回单个位?
祝你好运!
buffer[index/8] & (1u<<(index%8))
应该这样做(即,将 buffer
视为位数组并测试 index
处的位)。
类似地:
buffer[index/8] |= (1u<<(index%8))
应该设置 index-th
位。
或者您可以将 1 和 &
的八个移位状态中的 table 存储到
unsigned char bits[] = { 1u<<0, 1u<<1, 1u<<2, 1u<<3, 1u<<4, 1u<<5, 1u<<6, 1u<<7 };
如果您的编译器没有优化那些 /
和 %
以进行位运算(效率更高),那么:
unsigned_int / 8 == unsigned_int >> 3
unsigned_int % 8 == unsigned_int & 0x07 //0x07 == 0000 0111
所以
buffer[index>>3] & (1u<<(index&0x07u)) //test
buffer[index>>3] |= (1u<<(index&0x07u)) //set
您的函数的一种可能实现方式可能如下所示:
int read_single_bit(unsigned char* buffer, unsigned int index)
{
unsigned char c = buffer[index / 8]; //getting the byte which contains the bit
unsigned int bit_position = index % 8; //getting the position of that bit within the byte
return ((c >> (7 - bit_position)) & 1);
//shifting that byte to the right with (7 - bit_position) will move the bit whose value you want to know at "the end" of the byte.
//then, by doing bitwise AND with the new byte and 1 (whose binary representation is 00000001) will yield 1 or 0, depending on the value of the bit you need.
}
我想实现这样的功能:
int read_single_bit(unsigned char* buffer, unsigned int index)
其中索引是我想要读取的位的偏移量。
如何使用位移或掩码来实现此目的?
您可能希望将其分成三个独立的任务:
- 正在确定哪个
char
包含您要查找的位。 - 正在确定您需要读取的
char
的位偏移量。 - 实际从
char
中选择那个位。
我将把第 (1) 和 (2) 部分留作练习,因为它们还不错。对于第 (3) 部分,您可能会发现有用的一个技巧是在所讨论的字节与您想要的索引处具有单个 1
位的字节之间执行按位与运算。例如,假设您想要从一个字节中取出第四位。然后你可以这样做:
Byte: 11011100
Mask: 00001000
----------------
AND: 00001000
因此请考虑以下问题:如果您知道位索引,您将如何生成所需的掩码?以及如何将 AND 结果转换回单个位?
祝你好运!
buffer[index/8] & (1u<<(index%8))
应该这样做(即,将 buffer
视为位数组并测试 index
处的位)。
类似地:
buffer[index/8] |= (1u<<(index%8))
应该设置 index-th
位。
或者您可以将 1 和 &
的八个移位状态中的 table 存储到
unsigned char bits[] = { 1u<<0, 1u<<1, 1u<<2, 1u<<3, 1u<<4, 1u<<5, 1u<<6, 1u<<7 };
如果您的编译器没有优化那些 /
和 %
以进行位运算(效率更高),那么:
unsigned_int / 8 == unsigned_int >> 3
unsigned_int % 8 == unsigned_int & 0x07 //0x07 == 0000 0111
所以
buffer[index>>3] & (1u<<(index&0x07u)) //test
buffer[index>>3] |= (1u<<(index&0x07u)) //set
您的函数的一种可能实现方式可能如下所示:
int read_single_bit(unsigned char* buffer, unsigned int index)
{
unsigned char c = buffer[index / 8]; //getting the byte which contains the bit
unsigned int bit_position = index % 8; //getting the position of that bit within the byte
return ((c >> (7 - bit_position)) & 1);
//shifting that byte to the right with (7 - bit_position) will move the bit whose value you want to know at "the end" of the byte.
//then, by doing bitwise AND with the new byte and 1 (whose binary representation is 00000001) will yield 1 or 0, depending on the value of the bit you need.
}