11

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

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
4

3 に答える 3

14

1.#INF正の無限大です。正のフロートをゼロで除算すると得られます (フロートのゼロ自体をゼロで除算すると、結果は「非数値」になります)。

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

float fZero = 2 / nQuota;クラッシュの理由は、/演算子の両方のオペランドが整数であるため、整数に対して除算が実行されるためです。結果を float に格納してもかまいません。C++ には、ターゲット型付けの概念がありません。

整数への正の無限キャストが最小の整数である理由はわかりません。

于 2012-07-02T19:34:44.977 に答える
3

(float) または (double) を使用すると、クラッシュの 0 による除算が防止されるのはなぜですか?

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

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

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

  1. 簡単な答え: やらないでください。
    これは、「ドクター、ドクター、これをすると痛い!」の1つです。状況の種類。だからやらないで!

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

  3. 浮動小数点例外を有効にします。
    エラー (そしてこれらはほとんどの場合エラーです) がチェックされずに通過することを許可するデフォルトの動作を作成することは、標準化委員会の大きな間違いでした。デフォルトを使用すると、これらの無限大と非数は、最終的にすべてを Inf または NaN に変換します。
    デフォルトでは、1.0/0.0 や 0.0/0.0 などの発生を許可するオプションを使用して、トラック内の浮動小数点エラーを停止する必要がありました。そうではないため、これらのトラップを有効にする必要があります。そうすることで、多くの場合、問題の原因をすぐに見つけることができます。

  4. カスタム除算、カスタム乗算、カスタム平方根、カスタム正弦などの関数を記述します。
    残念ながら、これは多くの安全性が重要なソフトウェア システムが取らなければならないルートです。王道の痛みです。オプション #1 は希望的観測にすぎないため、使用できません。システムがクラッシュすることは許されないため、オプション #3 は使用できません。オプション #2 はまだ良いアイデアですが、常にうまくいくとは限りません。なぜなら、悪いデータには常に忍び込む方法があるからです。これはマーフィーの法則です。

ところで、問題はゼロ除算よりも少し悪いです。10 200 /10 -200もオーバーフローします。

于 2012-07-02T20:28:39.257 に答える
2

通常、ゼロで除算していないことを確認します。以下のコードは、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;
于 2012-07-02T19:39:22.350 に答える