我正在开发一个系统,要求我能够设置构成整数类型的各个位。
我写了一个程序来测试一些二元运算符的用法。以下是使用二进制OR运算符将位设置为true的小示例。但这种行为让我很困惑。如果我循环,将每个位设置为true,它会在第31位之后突然将所有位设置为true。我不确定为什么这会考虑我在64位机器上而且我使用numeric_limits
来获取位数。
#include <iostream>
#include <bitset>
#include <limits>
int main() {
typedef unsigned long long ullong;
ullong bits;
for(int i = 0; i < std::numeric_limits<ullong>::digits; ++i) {
bits |= (1 << i);
std::cout << std::bitset<std::numeric_limits<ullong>::digits>(bits) << "\n";
}
return 0;
}
该程序的输出如下:
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000011
0000000000000000000000000000000000000000000000000000000000000111
0000000000000000000000000000000000000000000000000000000000001111
0000000000000000000000000000000000000000000000000000000000011111
0000000000000000000000000000000000000000000000000000000000111111
0000000000000000000000000000000000000000000000000000000001111111
0000000000000000000000000000000000000000000000000000000011111111
0000000000000000000000000000000000000000000000000000000111111111
0000000000000000000000000000000000000000000000000000001111111111
0000000000000000000000000000000000000000000000000000011111111111
0000000000000000000000000000000000000000000000000000111111111111
0000000000000000000000000000000000000000000000000001111111111111
0000000000000000000000000000000000000000000000000011111111111111
0000000000000000000000000000000000000000000000000111111111111111
0000000000000000000000000000000000000000000000001111111111111111
0000000000000000000000000000000000000000000000011111111111111111
0000000000000000000000000000000000000000000000111111111111111111
0000000000000000000000000000000000000000000001111111111111111111
0000000000000000000000000000000000000000000011111111111111111111
0000000000000000000000000000000000000000000111111111111111111111
0000000000000000000000000000000000000000001111111111111111111111
0000000000000000000000000000000000000000011111111111111111111111
0000000000000000000000000000000000000000111111111111111111111111
0000000000000000000000000000000000000001111111111111111111111111
0000000000000000000000000000000000000011111111111111111111111111
0000000000000000000000000000000000000111111111111111111111111111
0000000000000000000000000000000000001111111111111111111111111111
0000000000000000000000000000000000011111111111111111111111111111
0000000000000000000000000000000000111111111111111111111111111111
0000000000000000000000000000000001111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111111
答案 0 :(得分:3)
这是因为1被视为整数,因此,当它被扩展为64位整数时,它被符号扩展。无符号整数是零扩展的。
这是积分扩展的两种不同行为。当积分类型转换为更大的整数类型时,整体扩展就会发生:计算机显然不能使新位随机,因此编译器会选择两种一致行为中的一种。
int
并使其成为long
,它仍然会是具有相同符号的相同数字。这是扩展有符号整数时通常会发生的情况。您还需要告诉编译器1至少与您的bits
变量一样大,因为否则1将会#34;脱落&#34;当你移动时:你将它移动到比int的大小更远的位置,所以它将被丢弃。您可以通过将1
转换为ullong
((ullong)1
),或者更简洁地使用ull
前缀1ull
来实现此目的。
答案 1 :(得分:1)
来自5.8 Shift运算符
操作数应为整数或无范围的枚举类型 进行整体促销。结果的类型是 晋升的左操作数。如果正确,行为是不确定的 操作数是负数,或大于或等于位的长度 提升的左操作数。
当我变成32时麻烦开始。换句话说,int32_t(1)&lt;&lt; 32是未定义的行为。