【发布时间】:2011-07-29 00:52:21
【问题描述】:
我不太擅长按位运算符,所以请原谅这个问题,但是我将如何清除 C/C++ 中 32 位整数的低 16 位?
例如,我有一个整数:0x12345678,我想将其设为:0x12340000
【问题讨论】:
标签: c bit-manipulation bitwise-operators
我不太擅长按位运算符,所以请原谅这个问题,但是我将如何清除 C/C++ 中 32 位整数的低 16 位?
例如,我有一个整数:0x12345678,我想将其设为:0x12340000
【问题讨论】:
标签: c bit-manipulation bitwise-operators
要清除任何特定的一组位,您可以使用按位 AND 与在这些位置具有 1 的数字的补码。在您的情况下,由于数字 0xFFFF 设置了它的低 16 位,您可以使用它的补码 AND:
b &= ~0xFFFF; // Clear lower 16 bits.
如果您想设置这些位,您可以改为使用按位 OR 与设置了这些位的数字:
b |= 0xFFFF; // Set lower 16 bits.
而且,如果您想翻转这些位,您可以使用按位异或与设置了这些位的数字:
b ^= 0xFFFF; // Flip lower 16 bits.
希望这会有所帮助!
【讨论】:
b & 0xFFFF0000 的操作,那么这可能会意外地最终清除高 32 位除了低 32 位。
0xffff 的类型为 int,即使 b 的类型为 unsigned long 等,在实际系统中几乎肯定是 32 位的。此外,~0xffff 具有实现定义的行为,因为0xffff 具有签名类型。请参阅我的答案以获得更好的方法。
要走另一条路,你可以试试
x = ((x >> 16) << 16);
【讨论】:
一种方法是将其与 0xFFFF0000 进行按位与,例如value = value & 0xFFFF0000
【讨论】:
使用 and (&) 和掩码,掩码由前 16 位全为 1(将保持高位保持原样)和低位全零(即将杀死数字的底部位)。
原来如此
0x12345678 & 0xffff0000
如果类型的大小未知并且您只想屏蔽低 16 位,您还可以通过另一种方式构建屏蔽:使用只允许通过低 16 位的屏蔽
0xffff
并用按位非 (~) 反转它,因此它将成为一个掩码,杀死仅低 16 位:
0x12345678 & ~0xffff
【讨论】:
int x = 0x12345678;
int mask = 0xffff0000;
x &= mask;
【讨论】:
假设您要从中清除位的值的无符号类型不是“小等级”,这是清除低 16 位的最安全、最便携的方法:
b &= -0x10000;
-0x10000 的值将通过模运算提升为b 的类型(无符号类型),导致所有高位被设置,低 16 位为零。
编辑: 实际上,James 的回答是最安全(最广泛的用例),但他的回答和我的回答推广到其他类似问题的方式有点不同,我的回答可能更适用于相关问题。
【讨论】:
b &= ~(1 ? 0xFFFF : b); 的事情?