难以理解编程中的按位运算符左移和右移功能

时间:2019-07-19 06:43:23

标签: c

在ANSI C第2.9节中,按位运算符使我无法理解此特定代码。

我知道每个按位运算符的工作原理,但是组合需要一些帮助。

getbits(x, 4, 3)

unsigned getbits(unsigned x, int p, int n) {
    return (x >> (p + 1 - n)) & ~(~0 << n);
}

2 个答案:

答案 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)