If I have a pointer to the start of a memory region, and I need to read the value packed in bits 30, 31, an开发者_Go百科d 32 of that region, how can I read that value?
Use bit masks.
It depends on how big a byte is in your machine. The answer will vary depending on if you're zero- or one-indexing for those numbers. The following function returns 0 if the bit is 0 and non-zero if it is 1.
int getBit(char *buffer, int which)
{
int byte = which / CHAR_BIT;
int bit = which % CHAR_BIT;
return buffer[byte] & (1 << bit);
}
If your compiler can't optimize well enough to turn the division and mod operations into bit operations, you could do it explicitly, but I prefer this code for clarity.
(Edited to fix a bug and change to CHAR_BIT, which is a great idea.)
I'd probably generalize this answer to something like this:
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;
}
Bit easier to use:
int i = 12345;
bool abit = get_bit(i, 4);
On a 32-bit system, you can simply shift pointer right 29. If you need the bit values in place, and by 0xE0000000.
精彩评论