【问题标题】:how to find left most 1 in a 32bit int in C [duplicate]如何在C中的32位int中找到最左边的1 [重复]
【发布时间】:2012-09-14 00:07:15
【问题描述】:

可能重复:
Find the highest order bit in C

如何编写一个 C 函数来生成一个掩码,该掩码指示 x 中最左边的 1

例如:0xFF00 -> 0x80000x6600 -> 0x4000。到目前为止:

int left1(unsigned x){}

我明白了,0xFF00 == 1111 1111 0000 0000..0x6600 == 0110 0110 0000 0000.. 但在那之后我很难过。

【问题讨论】:

  • 使用位移>>和屏蔽&
  • 如果你把它转换成签名的,你能不做 (x
  • 在这种情况下你如何处理字节序?最左边的位可能不是高位
  • @RichardJ.RossIII:没有任何进一步的阐述,这意味着“最左边”的意思是“最重要的”,因为我们就是这样写数字的。

标签: c bitwise-operators bitmask


【解决方案1】:

您可以分两部分进行:首先,使用一种称为“位涂抹”的技术来确保第一个 1 右侧的所有位也是 1:

x |= x >> 16;
x |= x >> 8;
x |= x >> 4;
x |= x >> 2;
x |= x >> 1;

此时,0xFF00 的输入将使x 等于0xFFFF0x6600 的输入将使x 等于0x7FFF。然后我们可以只保留最高的1 设置,使用:

x ^= x >> 1;

【讨论】:

  • 第一部分不应该是相反的顺序吗?
  • @alveko:无论哪种方式都一样好用。
  • 这不适用于负数,因为符号位是粘性的。
  • @don4of4:问题指定unsigned作为输入数字的类型。
【解决方案2】:

计算向右移位直到达到 1 所需的次数,然后将该 1 向左移位相同的次数。

int ct=0;
while (x > 1) { ct++; x = x >> 1; }
x = x << ct;

【讨论】:

    【解决方案3】:

    一种方法是创建一个位掩码,然后将值右移。

    也就是说,创建一个位掩码,使您的整数为 '1000....' 或 '0.....' - 取决于第一位是 0 还是 1。

    然后取那个整数并右移它,直到它变成最低有效位,而不是最高有效位。例如,0b10000000 &gt;&gt; 8 是 1。

    因此,首先,根据整数的大小,您必须进行移位,不管多少位都是相关的。

    然后您必须创建位掩码。我们只取一个 1 字节的整数:

    unsigned int i = 1 &lt;&lt; 8 将创建一个整数 i,其最高有效位为 1。

    或者你可以使用十六进制。你已经知道0xFF == 11111111。您实际上可以进一步分解:0xF0 == 11110000

    因为0xF == 1111 在二进制中,好吧,我们将做相反的事情。 1000 二进制是什么,十六进制?二进制中的1000 是数字8,也恰好等于0x8

    因此,对于单个字节,最左边位的掩码是0x80

    现在!将此应用于 32 位!

    祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-08
      • 1970-01-01
      • 1970-01-01
      • 2012-05-21
      • 1970-01-01
      • 2021-04-28
      相关资源
      最近更新 更多