难以理解 C 代码中用于屏蔽和位转换的语法

Trouble understanding syntax in C code for masking and bit conversion

下面的代码 returns 8 位二进制值中最后 6 位的带符号值,但是我很难理解代码是如何做到这一点的?任何帮助将不胜感激。

我理解 (b&0x20) returns 最后 6 位但是之后的 ? b 因此后续代码让我有点困惑。

return (b & 0x20) ? b | ~0x3F : b & 0x3F;

此代码可能是为以下情况编写的:

  • bint 或更窄。
  • 用补码表示负数。

?:构成条件运算。一般在X ? Y : Z中测试X。如果 X 不为零,则计算 Y 并将其用作表达式的结果。如果 X 为零,则计算 Z 并将其用作结果。

所以,在(b & 0x20) ? b | ~0x3F : b & 0x3F中,测试了(b & 0x20)b & 0x20b 中分离出 0x20 中的单个位,因此这是在测试该位置的位是否打开。

让我们首先考虑使用 b & 0x3F 时的“关闭”结果。 0x3F 是一个 int 值,低六位设置为 1,所有高位设置为 0。当它与 b 相与时,在 b & 0x3F 中,结果是b 的低六位,所有高位都设置为 0。作为 int,此结果具有 b.

的低六位的值

对于“on”结果,使用b | ~0x3F~ 运算符翻转每一位。由于 0x3F 的低六位设置为 1,所有高位设置为 0,因此 ~0x3F 的低六位设置为 0,所有高位设置为 1。当它与 b,在b | ~0x3F中,结果是b的低六位,所有高位都设置为1。

这样做是对b的低六位进行“符号扩展”:如果位置5(0x20)的位被清除,则(b & 0x20) ? b | ~0x3F : b & 0x3F的结果是b 的低六位,所有高位都被清除。如果设置了位置 5 中的位,则结果是 b 的低六位,所有高位都已设置。所以效果是位置 5 的位被复制到所有更高位。

当使用二进制补码时,扩展较窄类型的符号位会在较宽类型中产生相同的值。

例如,在三位二进制补码中:

  • 011代表3.
  • 010代表2.
  • 001代表1.
  • 000代表0.
  • 111代表-1。
  • 110代表-2.
  • 101代表-3.
  • 100代表-4。

当我们将它们符号扩展为 5 位时,我们有:

  • 00011代表3.
  • 00010代表2.
  • 00001代表1.
  • 00000代表0。
  • 11111代表-1。
  • 11110代表-2.
  • 11101代表-3.
  • 11100代表-4.

五位整数当然还有其他位模式,但这些是我们通过对三位整数进行符号扩展得到的。