INT_MIN-1はアンダーフローまたはオーバーフローですか?


10

私はそれを読んでいたことを覚えているようです

  • underflowマグニチュードが小さすぎてタイプで表示できないことを意味します
  • overflow大きさが大きすぎてタイプで表示できないことを意味します

ただし、実際には、これらの用語は次のように使用されていると思います。

  • underflowタイプで表示できないが小さすぎることを意味します
  • overflowタイプで表示できないが大きすぎることを意味します

ここで使用する正しい意味は何ですか?整数型と浮動小数点型で用語の定義は異なりますか?


2
一般に、「アンダーフロー」という用語は、浮動小数点演算用に予約されているようです。整数で、私は普通にかかわらず、それはだかどうかの「オーバーフロー」と言うINT_MIN - 1INT_MAX + 1
チャールズサルビア

回答:


15

これはおそらく慣例の問題であり、用語が非常に一貫していないことが多いため、この問題に関する「信頼できる」情報源を実際に見つけることはできません。しかし、Robert Seacordの「CおよびC ++でのセキュアコーディング」からの次の抜粋は、状況についての私の理解を要約したものです。

整数オーバーフローは、整数が最大値を超えて増加したり、最小値を超えて減少したりすると発生します3。整数オーバーフローは、基になる表現と密接に関連しています。

脚注はさらに続けます:

[3] 技術的にこの用語は浮動小数点条件を指しますが、最小値を超えて整数を減少させることは、しばしば整数アンダーフローと呼ばれます。

整数オーバーフローと呼ぶ理由は、値を表すのに十分なスペースが型で利用できないためです。その意味では、バッファオーバーフローと同様だ(むしろ実際のバッファ境界、それ通常展示ラップアラウンド動作を横切るより除く。*)このような観点から、間に概念的な差がないINT_MIN - 1とはINT_MAX + 1。どちらの場合も、intデータ型にはどちらの値も表すのに十分なスペースがないため、オーバーフローが発生します。

また、x86およびx86_64プロセッサアーキテクチャでは、フラグレジスタにオーバーフロービットが含まれていることに注意してください。オーバーフロービットは、符号付き整数の算術演算がオーバーフローすると設定されます。式INT_MIN - 1はオーバーフロービットを設定します。(「アンダーフロー」ビットはありません。)そのため、AMDおよびIntelのエンジニアは、「オーバーフロー」という用語を使用して、ビット数が多すぎてデータ型に収まらない整数算術演算の結果を説明します。数値が大きすぎるか小さすぎます。


*実際、Cでは、符号付き整数オーバーフローは実際には未定義の動作ですが、Javaなどの他の言語では、2の補数演算がラップアラウンドします。


6

オーバーフローです。整数値の場合、アンダーフローは発生しません。

オーバーフローとは、値が大きすぎて(ゼロから離れすぎて)特定のタイプで表現できない場合であり、アンダーフローとは、値が小さすぎる(ゼロに近すぎる)場合です。

ゼロに最も近い整数値(1と-1)は、任意の整数変数で表すことができるため(複数ビットの符号付き整数を想定)、アンダーフローは発生しません。

アンダーフロー上のWikipediaの記事はかなり明確な記述があります。

「算術アンダーフロー(または「浮動小数点アンダーフロー」、または単に「アンダーフロー」)という用語は、浮動小数点演算の実際の結果の大きさが小さい(つまり、ゼロに近い)場合に発生するコンピュータープログラムの条件です。ターゲットデータ型の通常の浮動小数点数として表現可能な最小値よりも小さい。アンダーフローは、浮動小数点値の指数の負のオーバーフローと一部見なすことができる。


underflow特に、数値の大きさが最小の非ゼロ値の大きさよりも小さいが、非ゼロ値間の最小の可能な距離よりも大きい特定の条件を参照するために頻繁に使用されることに注意してください。言葉、数字がウィキの記事が「アンダーフローギャップ」と呼ぶものに分類される場合。IEEE-744準拠の実装では、表現可能な最小の数値は、数値間の表現可能な最小の差に等しいため、このようなアンダーフローは発生しませんが、PCの世界以外では、すべてのシステムがIEEEに準拠しているわけではありません。
スーパーキャット2012

2

整数演算では、オーバーフローは大きすぎる値と小さすぎる値の両方を指します。浮動小数点では、オーバーフローは大きすぎる指数を指し、アンダーフローは小さすぎる指数を指します。

実際、整数型の場合、CPUにはオーバーフローとアンダーフローの違いを区別する方法がありません。次の16ビット加算を実行します。

  0x8000 (unsigned 32768, or signed -32767)
+ 0xFFFF (unsigned 65535, or signed -1)
--------
  0x7FFF (32767, the carried '1' is lost)

もちろん、CPUのオーバーフローフラグは、この追加後に設定されます。署名数学を使用して、結果があまりにもある小さな(-32768)。符号なし演算を使用して、結果があまりにもある(0x17FFF)。2の補数演算は、符号付きと符号なしの型で同じであるため、overflow値が大きすぎても小さすぎても意味します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.