从第 3 位开始读取 int 的最快方法?

Fastest way to read int starting from bit 3?

本文关键字:方法 int 开始 读取 从第      更新时间:2023-10-16

我正在尝试读取一个数字,大小为23位。该数字从第一个字节的第 3 位开始。

unsigned char c*;//byte array
unsigned int start_byte = 0;//the byte to start reading from
unsigned int start_bit = 2;//start reading from the 3rd bit
unsigned int length_in_bits = 23;//read a number of size 23 bits
unsigned int number;//store the number here

我可以在一个循环中通过许多左右移位来执行上述操作。
问题:从第一个字节的第 3 位开始,获取 23 位数字的最快方法是什么?

当我说第三位时,我的意思是:00x00000。该数字以大端格式存储。

注意:当我说 23 位数字、第 3 位时,这些都是变量。数字将从 1 位到 32 的任何值,起始位从 0 位到 7 的任何值。

这是一个对可变偏移量和字段宽度进行位移的版本。假定skip在 0 到 7 范围内,size在 1 到 32 范围内。size + skip可能超过 32,在这种情况下,将访问 5 个字节。此例程不记录读取后字节指针的位置,可以是从c + 1c + 5的任何位置。

uint32_t read_bits(const uint8_t *c, int skip, int size)
{
uint8_t m = (1 << (8 - skip)) - 1;
uint32_t u;
u = *c++ & m;
size -= (8 - skip);
while (size > 0) {
u = u << 8 | *c++;
size -= 8;
}
u >>= -size;
return u;
}

我只运行了一些粗略的测试,但看起来还可以。这可能也不是最快的方法。您可以查找表中的值,而不是使用位移来计算m

static const uint8_t mask[] = {
0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01
};
uint8_t m = mask[skip];

您可以使用位域。

struct Helper
{
unsigned int throwAway : 2;
unsigned int number :23;
};

然后在代码中:

Helper* helperPtr = reinterpret_cast<Helper*>(c);
for(int i=0;i<NUM_INTEGERS;++i)
std::cout << helperPtr[i].number <<" "; //integer #i

作为参考,请查看 http://msdn.microsoft.com/en-us/library/ewwyfdbe.aspx

相关文章: