我试图在长的无符号x中设置最重要的位。 要做到这一点,我使用这行代码:
x |= 1<<((sizeof(x)*8)-1);
我认为这应该可行,因为sizeof以字节为单位给出大小,所以我乘以8并减去1来设置最后一位。每当我这样做时,编译器都会收到此警告:“警告:左移计数&gt; =类型宽度”
我不明白为什么会出现这种错误。
答案 0 :(得分:16)
您要转移的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)
答案 1 :(得分:7)
使用1ULL&lt;&lt;而不是1&lt;&lt;&lt;
仅使用“1”可以移动整数。 1ULL将是一个无符号长的长,这是你需要的。
整数可能是32位,long long
可能是64位宽。如此转变:
1 << ((sizeof(long long)*8)-1)
将(最有可能):
1 << 63
由于1是(最可能)32位的整数,因此您会收到警告,因为您试图移过32位值的MSB。
答案 2 :(得分:1)
您正在移动的文字1
不会自动为unsigned long long
(而是int
),因此没有您需要的位数。将其与ULL
(即1ULL
)后缀,或将其转换为unsigned long long
,然后再转换为正确类型。
另外,为了让奇怪的平台更安全,请将8
替换为CHAR_BIT
。请注意,这仍然不一定是设置最高有效位的最佳方式,例如,请参阅this question替代方案。
如果您假设uint64_t
为特定宽度,则还应考虑使用unsigned long long
类型;如果您至少需要uint_fast64_t
/ uint_least64_t
,则应考虑使用uintmax_t
类型一定宽度,如果您需要最大可用类型,则为Scan
。
答案 3 :(得分:-1)
由于负整数的2的补码表示,最负的整数正是所需的位模式,只有MSB集。所以x |= (unsigned long long )LONG_LONG_MIN;
也应该有用。