2017-06-28 207 views
0

這裏意外的輸出是給了我意想不到的答案代碼左移位運算符C++

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

我得到的答案是0 但是,如果我行更改爲

cout<<pow(2, 50); 

我得到正確的答案。

有人可以解釋我的原因。

+1

整數溢出是我的猜測。 ('main.cpp:5:20:warning:左移count> = type [-Wshift-count-overflow]的寬度'編譯器警告是你的朋友,聽他們說) – Borgleader

+1

'1'有多少位? – ZDF

+0

確實「16工作?猜測你已經離開了左邊緣 –

回答

1

將「1」移出32位字段,結果爲零。 Pow使用浮點表示法,其中可以處理2^50。

EDIT

沒有像「1LL」或「1ULL」(這產生64位長數字)的任何修改,的整數,通常爲在x64或x86體系結構32位來處理。您可以使用

cout << (1ULL << 50); 

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

應該給它。

+0

什麼是32bit字段? – UnholySheep

+3

請注意'int'可能會或可能不是32位大。 – Rakete1111

+0

1被處理爲一個有32位的公用PC上的有符號整數。 – Loamsiada

3

假設你的編譯器將常量1視爲一個32位整數,你將它向左移動了很多,只有零位保留在32位中。 50大於32.

+0

那麼有什麼辦法可以轉換到50? –

+0

嘗試'1ULL << 50'。 – sharyex

+0

@VarunSaproo當然,只要把你的常量變成一個64位的變量。例如'#include '中的'int64_t'。 – nvoigt

2

從C++標準(5.8移位運算符)

1個所述的移位運算符< <和>>組左到右。

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

的操作數應爲整體的或無作用域枚舉類型並且執行 積分促銷。結果的類型是 升級的左操作數。 如果正確的 操作數是負數或大於或等於升級的左操作數的 位中的長度,則行爲未定義。

考慮到該行爲也將是不確定的,如果將右操作數不大於或等於在所述左操作數的位的長度,但是可以觸摸的符號位,因爲文字1整數具有類型signed int

至於這個函數調用pow(2, 50)那麼就使用了一些計算功率的算法。

1

這正是你在做什麼。你在32位內存中的一部分中將位置移動50位......根據你的情況發生了什麼?該位去其他地方,但它不在整數的內存部分。 pow(2, 50)執行double鑄造,所以你不再移動位。

此外,從來沒有使用#include<bits/stdc++.h>It's not standard,而且速度很慢。你應該只在預編譯頭文件中使用它,但在這種情況下我也會避免使用它。

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; 
} 
0
cout<<(1<<50); 

您的代碼把1int,所以溢出。相反,嘗試:

cout << (1ULL << 50);