Closed. This question is off-topic。它当前不接受答案。
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            想改善这个问题吗? Update the question,所以它是on-topic,用于堆栈溢出。
                        
                        6年前关闭。
                                                                                            
                
        
我正在尝试读取一个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


我可以循环进行许多左右移位的操作。
问题:从第1个字节的第3位开始,获取23位数字的最快方法是什么?

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

注意:当我说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];

关于c++ - 从第3位开始读取int的最快方法? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21268025/

10-11 22:54