如果我有一个指向内存区域开头的指针,并且我需要读取该区域的第30,31和32位打包的值,我该如何读取该值?
答案 0 :(得分:8)
使用bit masks。
答案 1 :(得分:3)
这取决于您机器中的字节大小。答案将根据您是否为这些数字进行零索引或一索引而有所不同。如果该位为0,则以下函数返回0;如果该位为1,则返回非零。
int getBit(char *buffer, int which)
{
int byte = which / CHAR_BIT;
int bit = which % CHAR_BIT;
return buffer[byte] & (1 << bit);
}
如果您的编译器无法很好地优化以将除法和mod操作转换为位操作,您可以明确地执行此操作,但为了清晰起见,我更喜欢此代码。
(编辑修复错误并更改为CHAR_BIT,这是一个好主意。)
答案 2 :(得分:1)
我可能会generalize this answer这样的事情:
template <typename T>
bool get_bit(const T& pX, size_t pBit)
{
if (pBit > sizeof(pX) * CHAR_BIT)
throw std::invalid_argument("bit does not exist");
size_t byteOffset = pBit / CHAR_BIT;
size_t bitOffset = pBit % CHAR_BIT;
char byte = (&reinterpret_cast<const char&>(pX))[byteOffset];
unsigned mask = 1U << bitOffset;
return (byte & mask) == 1;
}
更容易使用:
int i = 12345;
bool abit = get_bit(i, 4);
答案 3 :(得分:0)
在32位系统上,您只需将指针右移29.如果需要位值,则需要0xE0000000。