如何在C中找到有符号整数的最高有效位

How to find the most significant bit of a signed integer in C

我需要找到 signed int N 的最高有效位并将其保存在 signBitN 中。我想使用仅按位操作来执行此操作。 另外,我将如何使 signBitN 扩展以使其所有位都等于其有效位。 即如果它的有效位为零,我将如何将其扩展为 00000...00? 我得到的最接近的是 signBitN=1&(N>>(sizeof(int)-1));

便携表达式:

1 & (x >> (CHAR_BIT * sizeof(int) - 1))

最新的 C 标准对整数表示提出了 3 个标准。

  • 符号和大小
  • 补一
  • 二补 请参阅 C11 标准的 6.2.6.2 Integer types 部分。

只有第三个选项在实践中与现代机器相关。 如 6.2.6.1 中指定:

Values stored in non-bit-field objects of any other object type consist of n x CHAR_BIT bits, where n is the size of an object of that type, in bytes.

因此 int 将由 sizeof(int) * CHAR_BIT 位组成,可能是 32 位。 因此 int 的最高位可以通过右移 sizeof(int) * CHAR_BIT - 1 位并使用按位 & 运算符读取最后一位来读取。

请注意,移位后 int 的确切值是按照 6.5.7.5 中所述的实现定义的。

在正常的机器上它将是:

int y = x < 0 ? -1 : 0;

可移植的方式是在 intunsigned char 数组之间进行转换,并将所有字节设置为 -1。 见 6.3.1.3.2:

if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

6.2.6.1.2

Values stored in unsigned bit-fields and objects of type unsigned char shall be represented using a pure binary notation.

您可以使用 memset()

int x;
memset(&x, (x < 0 ? -1 : 0), sizeof x);

如果问题是如何检查整数的 MSB 位(例如 32 位整数的第 31 位)十 IMO 这是可移植的。

#define MSB(i)   ((i) & (((~0U) >> 1) ^ (~0U)))
#define issetMSB(i) (!!MSB(i))

int main(void)
{
    printf("%x\n", MSB(-1));
    printf("%x\n", issetMSB(-1));
}