正如问题标题所示,将2 ^ 31分配给有符号和无符号的32位整数变量会产生意外的结果。这是一个简短的程序(在C++中),我制作了这个程序以查看发生了什么:#include <cstdio>using namespace std;int main(){ unsigned long long n = 1<<31; long long n2 = 1<<31; // this works as expected printf("%llu\n",n); printf("%lld\n",n2); printf("size of ULL: %d, size of LL: %d\n", sizeof(unsigned long long), sizeof(long long) ); return 0;}这是输出:MyPC / # c++ test.cpp -o testMyPC / # ./test18446744071562067968 <- Should be 2^31 right?-2147483648 <- This is correct ( -2^31 because of the sign bit)size of ULL: 8, size of LL: 8然后,我向其中添加了另一个函数p():void p(){ unsigned long long n = 1<<32; // since n is 8 bytes, this should be legal for any integer from 32 to 63 printf("%llu\n",n);}在编译和运行时,这让我更加困惑:MyPC / # c++ test.cpp -o testtest.cpp: In function ‘void p()’:test.cpp:6:28: warning: left shift count >= width of type [enabled by default]MyPC / # ./test0MyPC /为何编译器会提示左移计数太大? sizeof(unsigned long long)返回8,那不是表示2 ^ 63-1是该数据类型的最大值吗?令我吃惊的是,也许n * 2和n void s(){ unsigned long long n = 1; for(int a=0;a<63;a++) n = n*2; printf("%llu\n",n);}这给出了正确的2 ^ 63值作为9223372036854775808输出(我使用python进行了验证)。但是,做左屎怎么了? A left arithmetic shift by n is equivalent to multiplying by 2n (provided the value does not overflow) -维基百科该值未溢出,因为该值为2 ^ 63(所有位均已设置),所以只会出现一个负号。我仍然无法弄清楚左移怎么回事,任何人都可以解释一下吗?PS:该程序在运行Linux Mint的32位系统上运行(如果有帮助的话) 最佳答案 在这行上:unsigned long long n = 1<<32;问题在于文字1的类型为int-可能只有32位。因此,这种转变将使它越界。仅仅因为您要存储到更大的数据类型中,并不意味着表达式中的所有内容都以该更大的大小完成。因此,要更正它,您需要将其转换或使其成为unsigned long long文字:unsigned long long n = (unsigned long long)1 << 32;unsigned long long n = 1ULL << 32;关于c++ - 将2 ^ 31分配给有符号和无符号32位整数变量后的结果很奇怪,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9973344/