繁体   English   中英

如何在 C 中找到已签名 integer 的最高有效位

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

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

便携表达:

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

最新的 C 标准将 3 个标准放在整数的表示上。

  • 符号和大小
  • 一补
  • 两个补码 请参阅第6.2.6.2 Integer types的 C11 标准。

只有第三种选择在实践中与现代机器相关。 6.2.6.1中所述:

存储在任何其他 object 类型的非位字段对象中的值由 nx CHAR_BIT 位组成,其中 n 是该类型的 object 的大小,以字节为单位。

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

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

在理智的机器上,它将是:

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

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

如果新类型是无符号的,则通过在新类型中可以表示的最大值的基础上反复加减一,直到该值在新类型的范围内。

6.2.6.1.2

存储在无符号位域和无符号字符类型对象中的值应使用纯二进制表示法表示。

您可以为此使用memset()

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

如果问题是如何检查 integer 的 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));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM