开发者

Reading bits in a memory

开发者 https://www.devze.com 2023-01-11 17:41 出处:网络
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

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号