在C中设置最重要的位
我试图在长的无符号x中设置最重要的位。 要做到这一点,我使用这行代码:
x |= 1<<((sizeof(x)*8)-1);
我认为这应该工作,因为sizeof以字节为单位给出大小,所以我乘以8并减去1来设置最后一位。 每当我这样做时,编译器都会出现此警告:“警告:左移计数> =类型的宽度”
我不明白为什么会出现这种错误。
您正在移位的1
是int
类型的常量,这意味着您将int
值移位sizeof(unsigned long long) * 8) - 1
位。 这种转变很容易超过int
的宽度,这显然就是你的情况。
如果要获得一些unsigned long long
类型的位掩码掩码,则应该使用unsigned long long
类型的初始位掩码,而不是int
类型。
1ull << (sizeof(x) * CHAR_BIT) - 1
构建相同掩模的一种可以说是更好的方法
~(-1ull >> 1)
要么
~(~0ull >> 1)
使用1ULL <<而不是1 <<
仅使用“1”可以移动整数。 1ULL将是一个无符号长的长,这是你需要的。 整数可能是32位, long long
整数可能是64位宽。 所以转移:
1 << ((sizeof(long long)*8)-1)
将(最有可能):
1 << 63
由于1是(最可能)32位的整数,因此您会收到警告,因为您试图移过32位值的MSB。
你正在移动的文字1
不是自动的unsigned long long
(但是int
),因此没有你需要的那么多位。 使用ULL
(即1ULL
)后缀,或者在移位前将其转换为unsigned long long
1ULL
,以使其成为正确的类型。
另外,为了让奇怪的平台更安全一点,用CHAR_BIT
替换8
。 请注意,这仍然不一定是设置最重要位的最佳方式,例如,请参阅此问题以寻找替代方案。
如果您假设unsigned long long
为某个宽度,则还应考虑使用uint64_t
这样的类型uint_least64_t
如果需要至少一定宽度,则应考虑使用uint_fast64_t
/ uint_least64_t
如果需要最大可用类型, uintmax_t
。
由于负整数的2的补码表示,最负的整数正是所需的位模式,只有MSB集。 所以x |= (unsigned long long )LONG_LONG_MIN;
也应该工作。