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



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

我知道(b&0x20)返回最后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 & 0x200x20中的单个位与b隔离,因此这是在测试该位置的位是否打开

让我们首先考虑使用b & 0x3F时的"关闭"结果。CCD_ 19是低6比特被设置为1并且所有较高比特被设置成0的CCD_。当这与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

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

相关内容

  • 没有找到相关文章

最新更新