-1
int main(){
    ll a=pow(2,32);
    cout <<a<<endl;
    cout << (-1<<1)<<endl;
    printf("%x",-1<<1);
}

上記のコードでは、次の出力が得られます。

4294967296
-2
fffffffe

4294967296fffffffe10進数では基本的に 16 進数と同じ2^32です。printf と cout の動作が異なるのはなぜですか? そして、このシフトはどのように正確に機能しますか?

4

8 に答える 8

1

初め、

基本的に2 ^ 32である16進数のfffffffe

間違っている。FFFFFFFE = 4294967294、つまり 2^32 - 2 (符号なし整数の場合) または -2 (2 の補数の 32 ビット符号付き整数の場合)。

次に、ほとんどの最新システムでは 32 ビットで printf("%x", ...)ある符号なし 16 進整数 (つまり) を出力します。適切に格納するには 64 ビット整数 (より正確には、少なくとも 33 ビット整数) が必要です。したがって、 を使用するときは、適切な型を持つ を呼び出します。つまり、printf 指定子で使用される型と C++オーバーロードで使用される強力な型が原因で、オーバーフローの問題が発生しています。unsigned intlong long a = 2 << 32cout << aostream& operator<<(ostream&, long long)operator<<

于 2013-10-25T14:51:20.253 に答える
0

最初のケースは有効です:正確な値 2 32を としてpow(2,32)返します。これは、変換しても正確なままです (これが謎の型であると仮定しています)。これを印刷することは完全に有効です。doublelong longllcout

の場合(-1<<1)、負の数を左シフトすると、未定義の動作が発生します。コンパイラが -2 として定義していても (ほとんどの場合)、printf%x指定子 (符号なしの型が必要) で使用するために負の数を渡すことも未定義の動作です。

于 2013-10-25T15:01:49.383 に答える
0

%x は 16 進数で、cout は数値 (int) を直接出力するだけなので、-1 は 0xFFFFFFFF です。左にシフトすると、0 を追加する必要があります。つまり、最後の F (バイナリでは 1111 が 1110 になります。つまり、E になります)あなたのポイントにもっと明確に答えてください....

于 2013-10-25T14:49:03.220 に答える
0

%x出力をフォーマットして値を 16 進数で表示するため、同じことを行うにstd::hexはに渡す必要があります。cout

std::cout << std:::hex << (-1<<1) << endl;
             ^^^^^^^^^
于 2013-10-25T14:46:26.247 に答える