使用左移运算符C ++的意外输出

时间:2017-06-28 12:39:04

标签: c++

这是给我意想不到的答案的代码

#include<bits/stdc++.h>
using namespace std;
int main()
{
    cout<<(1<<50);
}

我得到的答案是0。 但是,如果我将行更改为

cout<<pow(2, 50);

我得到了正确答案。

有人可以解释一下原因。

6 个答案:

答案 0 :(得分:3)

假设您的编译器将常量1视为32位整数,则将其向左移动到左侧,只有零位保留在您拥有的32位中。 50大于32。

答案 1 :(得分:2)

来自C ++标准(5.8移位运算符)

  

1移位运算符&lt;&lt;和&gt;&gt;从左到右分组。

shift-expression:
    additive-expression
    shift-expression << additive-expression
    shift-expression >> additive-expression
  

操作数应为整数或无范围的枚举类型   进行整体促销。结果的类型是   晋升的左操作数。 如果正确,则行为未定义   操作数是负数,或大于或等于中的长度   提升左操作数的位

考虑到如果右操作数不大于或等于左操作数的位长度但是可以触摸符号位,则行为也将是未定义的,因为整数文字1具有类型{ {1}}。

对于这个函数调用signed int,然后使用一些计算功率的算法。

答案 2 :(得分:2)

试试这个(run it):

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

答案 3 :(得分:1)

您将“1”移出32位字段,因此结果为零。 Pow使用float表示,其中可以处理2 ^ 50。

<强> 修改

没有任何修改,如“1LL”或“1ULL”(生成长64位数字),整数通常在x64或x86架构上处理为32位。你可以使用

 cout << (1ULL << 50);

 cout << ((long long)1 << 50);

应该是它。

答案 4 :(得分:1)

这正是你正在做的事情。你在一个32位的内存中将一个位移了50位......根据你的情况发生了什么?该位在其他地方,但它不再在整数的内存部分内。 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <body ng-app="myApp" ng-controller="ctrl"> <table> <tr><th>Week</th><th>Day</th></tr> <tr ng-repeat="week in weeks_and_days"><td>{{week.week_nr}}</td><td ng-repeat="day in week.day_nr">{{day}}&nbsp;</td></tr> </table> </body>执行pow(2, 50)投射,因此您不再转移位。

此外,请勿使用doubleIt's not standard,而且速度很慢。您应该只在预编译的头文件中使用它,但在这种情况下我也要避免使用它。

答案 5 :(得分:0)

cout<<(1<<50);

您的代码将1视为int,因此溢出。相反,尝试:

cout << (1ULL << 50);