简体   繁体   中英

Unexpected output with left shift operator C++

Here is the code which is giving me the unexpected answer

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

The answer I get is 0. But if I change the line to

cout<<pow(2, 50);

I get the right answer.

Could someone explain me the reason.

Assuming your compiler treats the constant 1 as a 32bit integer, you shifted it so far to the left, that only zeroes remain in the 32bit you have. 50 is larger than 32.

From the C++ Standard (5.8 Shift operators)

1 The shift operators << and >> group left-to-right.

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

The operands shall be of integral or unscoped enumeration type and integral promotions are performed. The type of the result is that of the promoted left operand. The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand .

Take into account that the behavior also will be undefined if the right operand is not greater or equal to the length in bits of the left operand but can touch the sign bit because the integer literal 1 has the type signed int .

As for this function call pow(2, 50) then there is used some algorithm that calculates the power.

Try this ( 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;
}

You shift the "1" out of the 32 bit field, so zero is the result. Pow uses float representation where 2^50 can be handled.

EDIT

Without any modifications like "1LL" or "1ULL" (which generate long 64bit numbers), an integer number is usually handled as 32 bit on a x64 or x86 architectures. You can use

 cout << (1ULL << 50);

or

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

which should to it.

It's exactly what you're doing. You're shifting a single bit by 50 position in a portion of memory that's 32 bit... What's happening according to you? The bit goes somewhere else but it's not inside the memory portion of the integer anymore. pow(2, 50) performs a double casting, so you're not shifting bits anymore.

Also, never use #include<bits/stdc++.h> . It's not standard , and it's slow. You should use it only in precompiled headers but I'd avoid this also in that cases.

cout<<(1<<50);

Your code treats 1 as an int , so overflows. Instead, try:

cout << (1ULL << 50);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM