难以理解 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;
此代码可能是为以下情况编写的:
b
是 int
或更窄。
- 用补码表示负数。
?
和:
构成条件运算。一般在X ? Y : Z
中测试X
。如果 X
不为零,则计算 Y
并将其用作表达式的结果。如果 X
为零,则计算 Z
并将其用作结果。
所以,在(b & 0x20) ? b | ~0x3F : b & 0x3F
中,测试了(b & 0x20)
。 b & 0x20
从 b
中分离出 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.
五位整数当然还有其他位模式,但这些是我们通过对三位整数进行符号扩展得到的。
下面的代码 returns 8 位二进制值中最后 6 位的带符号值,但是我很难理解代码是如何做到这一点的?任何帮助将不胜感激。
我理解 (b&0x20)
returns 最后 6 位但是之后的 ? b
因此后续代码让我有点困惑。
return (b & 0x20) ? b | ~0x3F : b & 0x3F;
此代码可能是为以下情况编写的:
b
是int
或更窄。- 用补码表示负数。
?
和:
构成条件运算。一般在X ? Y : Z
中测试X
。如果 X
不为零,则计算 Y
并将其用作表达式的结果。如果 X
为零,则计算 Z
并将其用作结果。
所以,在(b & 0x20) ? b | ~0x3F : b & 0x3F
中,测试了(b & 0x20)
。 b & 0x20
从 b
中分离出 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.
五位整数当然还有其他位模式,但这些是我们通过对三位整数进行符号扩展得到的。