2012-07-02 7 views
8

1.#INFとは何ですか?また、floatまたはdoubleへのキャストは、0のクラッシュによる除算を防止するのはなぜですか?
また、0による除算を防止する方法の素晴らしいアイデアですか? (マクロやテンプレートのように)?0除算による除算

int nQuota = 0; 

int nZero = 3/nQuota; //crash 
cout << nZero << endl; 

float fZero = 2/nQuota; //crash 
cout << fZero << endl; 

私の代わりに使用している場合:

int nZero = 3/(float)nQuota; 
cout << nZero << endl; 
//Output = -2147483648 

float fZero = 2/(float)nQuota; 
cout << fZero << endl; 
//Output = 1.#INF 
+2

すごく面白いです。答えを楽しみにしています。 –

+0

これはあなたにとって興味深いかもしれません:http://blog.regehr.org/archives/721 – cppanda

答えて

12

1.#INFが正の無限大です。正の浮動小数点を0で割ったときに得られます(浮動小数点のゼロ自体を0で除算すると、結果は「数ではありません」)。

一方、整数をゼロで除算すると、プログラムがクラッシュします。

理由がfloat fZero = 2/nQuota;であるのは、/演算子の両方のオペランドが整数なので、除算が整数で実行されるためです。結果をフロートに格納することは重要ではありません。 C++には、ターゲットタイピングの概念はありません。

整数への正の無限大のキャストが最小の整数なので、わかりません。

+0

何について-2147483648? –

+1

-2147483648は1です。#INFは整数にキャストされます。 –

+3

C仕様では、NaNまたは無限のfloat値を整数に変換した結果は指定されていません。浮動小数点数が無限大またはNaNの場合、浮動小数値の整数部分が 整数型の範囲を超える場合、無効な浮動小数点例外が発生し、結果の値が指定されません。 – mkb

1

通常、ゼロで除算していないことを確認します。 nQuotaが正当な値を持っていない限り、以下のコードは特に有用ではないが、(フロート)または(二重)を使用してクラッシュ

int nQuota = 0; 
int nZero = 0; 
float fZero = 0; 
if (nQuota) 
    nZero = 3/nQuota; 
cout << nZero << endl; 

if (nQuota) 
    fZero = 2/nQuota; 
cout << fZero << endl; 
+0

シンプルだけど、そのような魅力。 –

3

Wwhyを防止ないクラッシュの0による除算を防ぎますか?

必ずしもそうではありません。浮動小数点の場合、標準は驚くほどのスペアです。ほとんどのシステムでは現在IEEE浮動小数点標準が使用されています。つまり、ゼロ除算のデフォルトアクションは、クラッシュするのではなく、±無限大を返すことです。適切な浮動小数点例外を有効にすることでクラッシュさせることができます。

注意:浮動小数点例外モデルとC++例外モデルの共通点は、単語「例外」だけです。私が作業するすべてのマシンで、浮動小数点例外はC++例外をスローしません。

また、0による除算を防止する方法についての素晴らしいアイデアはありますか?

  1. 簡単な答えは:それをしないでください。
    これは "医者、医者は私がこれをすると痛い!"状況の種類。だからやってはいけない!

  2. 除数がゼロでないことを確認してください。
    ユーザー入力である除数の正常性チェックを実行します。常にユーザーの入力をフィルタリングして健全性を確保します。数字が何百万になると想定されているときにユーザー入力値が0になると、オーバーフロー以外にあらゆる種類の混乱が発生します。中間値を健全性チェックします。

  3. 浮動小数点例外を有効にします。
    エラーが(ほとんどの場合エラーですが)チェックされないようにするためのデフォルトの動作を行うことは、IMHOが標準委員会の大きな間違いでした。デフォルトと無限大を使用して、数字ではなくても結局すべてをInfかNaNに変換します。
    デフォルトでは、1.0/0.0や0.0/0.0などのようなものを可能にするオプションを使用して、トラック内の浮動小数点エラーを停止する必要がありました。そうではないので、これらのトラップを有効にする必要があります。それを行うと、しばしば問題の原因を短い順序で見つけることができます。

  4. カスタム除算、カスタム乗算、カスタム平方根、カスタムサイン、...関数を作成します。
    これは残念なことに、多くの安全上重要なソフトウェアシステムで必要とされるルートです。それは王様の痛みです。オプション1は外に出ています。それは単に希望的な考えであるからです。システムがクラッシュすることができないため、オプション#3が出ています。オプション2はまだまだ良いアイデアですが、悪いデータには常に息を呑むような方法があるので、それは必ずしも機能しません。それはマーフィーの法則です。

ところで、この問題はちょうど0除算よりも悪いです。 10 /10 -200もオーバーフローします。