这是给我意外答案的代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
cout<<(1<<50);
}
我得到的答案是0。但是,如果我将行更改为
cout<<pow(2, 50);
我得到了正确的答案。
有人可以向我解释原因。
假设您的编译器将常数1
视为32位整数,您将其移至左侧,仅在32位中只保留零。50大于32。
尝试此(运行(:
#include <iostream>
int main()
{
std::int64_t i { 1 }; // wide enough to allow 50 bits shift
std::cout << std::hex << ( i << 50 ); // should display 4000000000000
return 0;
}
来自C 标准(5.8 Shift Operators(
1换档运算符&lt;&lt;>>从左到右。
shift-expression:
additive-expression
shift-expression << additive-expression
shift-expression >> additive-expression
操作数应具有不可或缺的枚举类型,并且 进行积分促销。结果的类型是 晋升的左操作数。如果正确的话,行为是不确定的 操作数为负面,或大于或等于长度 晋升的左操作数。
考虑到正确的操作数不大或等于左操作数位的长度,但可以触摸符号位,因为整数1
具有signed int
类型。
至于此功能调用pow(2, 50)
,则使用了一些计算功率的算法。
您将" 1"移出32位字段,因此结果为零。POW使用可以处理2^50的浮点表示。
edit
没有任何修改,例如" 1ll"或" 1ull"(生成长64位数字(,整数通常在x64或x86体系结构上以32位处理。您可以使用
cout << (1ULL << 50);
或
cout << ((long long)1 << 50);
应该为此。
这正是您在做什么。您正在在32位的一部分内存中移动一个位置50位...根据您的说法是什么?钻头在其他地方,但它不再在整数的内存部分内。pow(2, 50)
执行double
铸件,因此您不再转移位。
另外,切勿使用#include<bits/stdc++.h>
。这不是标准的,而且很慢。您应该仅在预编译的标题中使用它,但在这种情况下我也会避免使用它。
cout<<(1<<50);
您的代码将1
视为int
,因此溢出。而是尝试:
cout << (1ULL << 50);