1. ホーム
  2. c++

[解決済み】C++で(-2147483648> 0)がtrueを返す?

2022-04-01 08:50:18

質問

-2147483648は32ビットの整数型では最小の整数ですが、この整数型ではオーバーフローするようです。 if(...) という文章があります。

if (-2147483648 > 0)
    std::cout << "true";
else
    std::cout << "false";

これは、次のように表示されます。 true をテストしてみました。しかし、-2147483648を整数にキャストすると、結果は違ってきます。

if (int(-2147483648) > 0)
    std::cout << "true";
else
    std::cout << "false";

これは、次のように表示されます。 false .

混乱しています。どなたか解説をお願いします。


2012年05月02日更新

コメントありがとうございます。私のコンパイラでは、intのサイズは4バイトです。VCは簡単なテストに使っています。質問文の記述を変更しました。

この投稿には、とても良い返事がたくさんありますね。 アンドレイ は、このような入力に対してコンパイラがどのように動作するか、また、この最小整数がどのように実装されたかについて、非常に詳細な説明をしています。 qPCR4vir 一方、関連する好奇心や、整数がどのように表現されるかを説明しました。とても印象的でした。

解き方は?

-2147483648 は、quot;number" ではありません。C++言語は負のリテラル値をサポートしていません。

-2147483648 は実際には式であり、正のリテラル値である 2147483648 と単項の - 演算子を前に置く。値 2147483648 のプラス側に対して大きすぎるようです。 int の範囲にあります。もし、タイプ long int がより大きな範囲を持っていた場合、コンパイラは自動的に 2147483648 があります。 long int という型があります。(C++11では、コンパイラはさらに long long int という型があります)。この場合、コンパイラは -2147483648 を、より大きな型の領域で実行すると、結果は予想通り負になる。

しかし、どうやらあなたの場合は long int の範囲と同じです。 int よりも大きな範囲を持つ整数型はありません。 int を使用することができます。これは形式的には、正の定数 2147483648 は利用可能なすべての符号付き整数型をオーバーフローさせるので、 プログラムの動作は未定義になります。(このような場合、言語仕様が診断メッセージを必要とせず、未定義の動作を選択するのは少し不思議ですが、そういうものです)。

実際には、動作が未定義であることを考慮した上で 2147483648 は、実装依存の負の値として解釈され、単項演算子の後にたまたま正に転じるかもしれません。 - が適用されます。あるいは、実装によっては、符号なし型を使用して値を表現することを試みるかもしれません(例えば、C89/90コンパイラでは、符号なし型を使用することを要求されました)。 unsigned long int しかし、C99やC++ではそうではありません)。どうせ動作は未定義なので、実装者は何をしてもよいのです。

余談ですが、このような定数で INT_MIN は通常、次のように定義されます。

#define INT_MIN (-2147483647 - 1)

の代わりに、一見するともっと簡単な

#define INT_MIN -2147483648

後者は意図したとおりに動作しないでしょう。