在ANSI C第2.9节中,按位运算符使我无法理解此特定代码。
我知道每个按位运算符的工作原理,但是组合需要一些帮助。
getbits(x, 4, 3)
unsigned getbits(unsigned x, int p, int n) {
return (x >> (p + 1 - n)) & ~(~0 << n);
}
答案 0 :(得分:4)
~0
是由二进制(int
)组成的111...111111
~0<<n
在低位(n
)中引入111...111000
零。
~(~0<<n)
翻转位(000...000111
)
x>>(p+1-n)
将x
向低位(00XXX...XXXXXX
)移动。
&
操作结合了前两个结果:高位零保持为零,低位X
(面对那些)保持原样(00000...000XXX
)。
因此,此函数从n
位中检索x
位的p
位模式,但将(p+1-n)
位向较低位移动(即,放置在较低位置)
答案 1 :(得分:2)
该功能应该在位置n
处提取一个宽度为p
的位域。
此功能有问题:
p + 1 - n
似乎是伪造的,但是如果p
是位域中最高有效位的位数,则为{{1 }}的最低有效位。
如果0
是有符号整数,则在位域中包含x
的最高有效位时,该代码具有实现定义的行为。应该使用0
。
该代码无法提取具有0U
完整宽度的位域,因为移位大于或等于该类型宽度的位数具有不确定的行为。移位应分为unsigned int
位和另外的1位两部分。 n - 1
的范围为n - 1
,因此变量移位已完全定义。
这是更便于携带的版本:
[0..31]
以下是步骤:
// extract `n` bits at position `p`. n in [1..32], p in `[1..32]`
unsigned getbits(unsigned x, int p, int n) {
return (x >> (p + 1 - n)) & ~(~0U << (n - 1) << 1);
}
是unsigned int空常量。0U
的所有值都已设置。~0U
的所有值位都已设置,除了~0 << (n - 1)
低位已清除。n - 1
的所有值位都已设置,除了~0 << (n - 1) << 1
低位已清除。n
设置了~(~0 << (n - 1) << 1)
低位。n
是比位域低位的位数p + 1 - n
将值向右移动,将位字段保留在低位位。x >> (p + 1 - n)
屏蔽高阶位,仅保留位域值。请注意,还有其他计算掩码的方法:
(x >> (p + 1 - n)) & ~(~0 << (n - 1) << 1)