带有左移操作员C 的意外输出

Unexpected output with left shift operator C++

本文关键字:意外 输出 操作员 左移      更新时间:2023-10-16

这是给我意外答案的代码

#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);