簡體   English   中英

使用左移運算符C ++的意外輸出

[英]Unexpected output with left shift operator C++

這是給我意想不到的答案的代碼

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

我得到的答案是0。但是如果我將行更改為

cout<<pow(2, 50);

我得到正確的答案。

有人可以向我解釋原因。

假設您的編譯器將常數1視為32位整數,則將其向左移動了很遠,這樣在您擁有的32位中只有零。 50大於32。

從C ++標准(5.8移位運算符)開始

1移位運算符<<和>>從左到右分組。

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

操作數應為整數或無作用域枚舉類型,並執行整數提升。 結果的類型是提升后的左操作數的類型。 如果右操作數為負或大於或等於提升后的左操作數的位長度, 則該行為是不確定的

請注意,如果右操作數不大於或等於左操作數的位長度,但由於整數文字1的類型為signed int類型,因此可以觸摸符號位,因此行為也將不確定。

對於此函數調用pow(2, 50) ,則使用某種算法來計算功率。

試試這個( 運行它 ):

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

您將“ 1”移出了32位字段,因此結果為零。 Pow使用浮點表示形式,可以處理2 ^ 50。

編輯

如果不進行任何類似“ 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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM