【问题标题】:Clear lower 16 bits清除低 16 位
【发布时间】:2011-07-29 00:52:21
【问题描述】:

我不太擅长按位运算符,所以请原谅这个问题,但是我将如何清除 C/C++ 中 32 位整数的低 16 位?

例如,我有一个整数:0x12345678,我想将其设为:0x12340000

【问题讨论】:

    标签: c bit-manipulation bitwise-operators


    【解决方案1】:

    要清除任何特定的一组位,您可以使用按位 AND 与在这些位置具有 1 的数字的补码。在您的情况下,由于数字 0xFFFF 设置了它的低 16 位,您可以使用它的补码 AND:

    b &= ~0xFFFF; // Clear lower 16 bits.
    

    如果您想设置这些位,您可以改为使用按位 OR 与设置了这些位的数字:

    b |= 0xFFFF; // Set lower 16 bits.
    

    而且,如果您想翻转这些位,您可以使用按位异或与设置了这些位的数字:

    b ^= 0xFFFF; // Flip lower 16 bits.
    

    希望这会有所帮助!

    【讨论】:

    • 这实际上很好,因为它也适用于 16 位和 64 位值,如果我没记错的话。
    • @James- 如果您尝试在非 32 位机器(例如,64 位机器)上执行类似 b & 0xFFFF0000 的操作,那么这可能会意外地最终清除高 32 位除了低 32 位。
    • 它不适用于 64 位值。 0xffff 的类型为 int,即使 b 的类型为 unsigned long 等,在实际系统中几乎肯定是 32 位的。此外,~0xffff 具有实现定义的行为,因为0xffff 具有签名类型。请参阅我的答案以获得更好的方法。
    • 你能告诉我,如果 0x12345678 我想做那个:0x00005678,还是我应该打开另一个问题?
    【解决方案2】:

    要走另一条路,你可以试试

    x = ((x >> 16) << 16);
    

    【讨论】:

      【解决方案3】:

      一种方法是将其与 0xFFFF0000 进行按位与,例如value = value &amp; 0xFFFF0000

      【讨论】:

        【解决方案4】:

        使用 and (&amp;) 和掩码,掩码由前 16 位全为 1(将保持高位保持原样)和低位全零(即将杀死数字的底部位)。

        原来如此

        0x12345678 & 0xffff0000
        

        如果类型的大小未知并且您只想屏蔽低 16 位,您还可以通过另一种方式构建屏蔽:使用只允许通过低 16 位的屏蔽

        0xffff
        

        并用按位非 (~) 反转它,因此它将成为一个掩码,杀死仅低 16 位:

        0x12345678 & ~0xffff
        

        【讨论】:

          【解决方案5】:
          int x = 0x12345678;
          int mask = 0xffff0000;
          
          x &= mask;
          

          【讨论】:

            【解决方案6】:

            假设您要从中清除位的值的无符号类型不是“小等级”,这是清除低 16 位的最安全、最便携的方法:

            b &= -0x10000;
            

            -0x10000 的值将通过模运算提升为b 的类型(无符号类型),导致所有高位被设置,低 16 位为零。

            编辑: 实际上,James 的回答是最安全(最广泛的用例),但他的回答和我的回答推广到其他类似问题的方式有点不同,我的回答可能更适用于相关问题。

            【讨论】:

            • 为什么不做类似b &amp;= ~(1 ? 0xFFFF : b); 的事情?
            猜你喜欢
            • 2014-05-20
            • 1970-01-01
            • 2014-10-21
            • 2012-12-31
            • 2015-05-21
            • 1970-01-01
            • 2014-05-23
            • 1970-01-01
            相关资源
            最近更新 更多