如何从C中的数字中提取特定位?

Usm*_*man 19 c bit-manipulation bit-shift bit

我需要在C中提取short数据类型的特定部分(没有位).

例如,我的二进制52504为11001101000 11000,我想要前6(FROM LSB - > MSB即011000十进制24)位和其余10位(11001101000十进制820).

类似地,我希望这个函数过于通用,不能提取给定"start"和"end"的特定位数(即位块等效于一些十进制值).

我检查了其他帖子,但那些没有帮助,因为给定的功能没有太多的概括.

我需要一些可以用于shortC数据类型的东西.

编辑

我有2048字节的短数组.每个像素为10位.所以我的16位组成每个字节占用一些时间2像素数据,有时3像素数据.

喜欢

(PIXEL:0,1)10 BITS + 6 BITS

然后(PIXEL:1,2,3)4 BITS(剩余第1个像素位)+ 10个BITS + 2个BITS.

等等..这个模式继续......所以,我想要提取每个像素并制作一个整个数组,让每个像素被占用在整个字节(16位)上,如... 1字节应该包含1 DATA PIXEL,另一个BYTE应该包含整个16位的其他PIXEL值,依此类推.

das*_*ght 24

您需要了解两个构建块来自行构建:

  • 获得N最低有效位需要在末尾构造一个带有掩码位掩码N.你这样做:((1 << N)-1).1 << N2 ^ N:它1N+1st位置有一个,并且在它之后全部为零.减去一个可以为你提供所需的面具.
  • 删除M最低有效位是向右移动的简单方法:k >> M

现在你从切割算法M,以N成为一个两步的过程:你原来值偏移M位到右侧,然后执行逐位AND与面具N-M的人.

#define LAST(k,n) ((k) & ((1<<(n))-1))
#define MID(k,m,n) LAST((k)>>(m),((n)-(m)))

int main() {
    int a = 0xdeadbeef;
    printf("%x\n",  MID(a,4,16));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

此片段将从4(包括)的位切除到16,独占,并bee在运行时打印.位从零开始编号.


And*_*nck 13

unsigned short extract(unsigned short value, int begin, int end)
{
    unsigned short mask = (1 << (end - begin)) - 1;
    return (value >> begin) & mask;
}
Run Code Online (Sandbox Code Playgroud)

请注意,这[begin, end)是一个半开的间隔.


060*_*002 9

它可以这样做:

mask = ~(~0 << (end - start + 1));
value = (n >> start) & mask;
Run Code Online (Sandbox Code Playgroud)

其中n是原始整数,value是提取的位.

mask构造是这样的:

1. ~0 = 1111 1111 1111 1111 1111 1111 1111 1111
2. ~0 << (end - start + 1) = 1111 1111 1111 1111 1100 0000 0000 0000
   // assuming we are extracting 14 bits, the +1 is added for inclusive selection
   // ensure that end >= start
3. ~(~0 << (end - start + 1)) = 0000 0000 0000 0000 0011 1111 1111 1111
Run Code Online (Sandbox Code Playgroud)

现在n逐位移start位以将所需位对齐到左侧.然后按位AND给出结果.