- 締切済み
分数の分母ゼロ問題
分数の計算で分母がゼロになると当然発散するわけですが、その回避の方法として以下のようなものを考えています。 x=1.0 y=0.0 a=x/y ! a=∞ ゼロ割計算が一旦発生する b=y/x ! b=0.0 if(y.eq.0.) then c=a ! しかしここでaを採用しないのでプログラムには関係なし。 else c=b ! こちらが選択される。 endif というようなものです。一旦ゼロ割が生じるけれどもそれを採用しないのでトラブル回避という格好です。このような方法は問題ないと考えられるでしょうか。 もちろん、このような簡単なプログラムではありません。複雑なアルゴリズムの中の1つの局面でこのような処理をするということです。それとも絶対このような処理は行うべきではないのでしょうか。 実験すべきかと思いますが、本当の方は複雑なので実験結果があてはまるかどうかも分からないものですので。 よろしくお願いします。
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- notnot
- ベストアンサー率47% (4900/10359)
#3です。 >このプログラムではゼロ割しても後の処理でその問題を回避する処置がなされるため体勢に影響はないという解釈が成り立ちます。 そのような(ゼロで割った時点でエラーが発生しないが、その結果を格納した変数を参照した時点でエラーになる)言語は今のところ実在しないでしょうね。わざとそういう言語を作れば作れますが。 実在する言語では、 ケース1: ゼロで割った時点でエラーになり、プログラムが異常終了する。異常終了を回避できない ケース2: ゼロで割った時点でエラーになり、割り込みが発生して、あらかじめ指定した処理が動く。特に処理を指定しないとプログラムが異常終了する ケース3: 演算結果として無限大相当の値を取り、エラーにならず処理続行 のいずれかです。ほとんどの実用言語はケース2だと思います。 ケース3の例としてはRubyですね。Rubyのfloat型は、通常の実数値(Cのdouble)の他にInfinty,-Infinity,NaN(=Not a Number=非数=0.0/0.0) の値も取れ、a=1.0/0.0 だと、a には Infinity が入ります。他にも数学関係の言語でも無限大を扱えると思いますよ。 したがって、 >どんな言語、どんな処理系でもこれが生じたらそのシステムは異常終了するのである は間違っています。
- Tacosan
- ベストアンサー率23% (3656/15482)
「割り算の前にチェックする」のに比べて「明確なメリット」が見えないんですけど....
- ultraCS
- ベストアンサー率44% (3956/8947)
その考え方だと、分子も0の時には通用しないとおもいますがね。 除数と被除数は両方調べる必要がありますし、実数の除算の場合、アンダーフローやオーバーフローまで含めて考えないと意味がありません。
- notnot
- ベストアンサー率47% (4900/10359)
数学の話じゃなくて、プログラミングの話なら、実数のゼロ除算でどうなるかは言語によって違いますので、特定言語に限定して話さないと意味がないです。 ・例外が発生。例外処理を記述できる ・例外が発生。例外処理を記述できない ・結果が浮動小数点の無限大になり、処理続行 などなど 例外が発生するケースでは、a=x/y の時点で発生するので、その後のif文の実行がどうなるかは関係ないです。
お礼
回答、有り難うございます。 ご指摘の内容はコンパイラ、処理系、言語など諸々の条件によっていろいろ変わるということかと思います。 このプログラムではゼロ割しても後の処理でその問題を回避する処置がなされるため体勢に影響はないという解釈が成り立ちます。ゼロ割した変数の内容をその後参照しないからですね。コンパイラがそのように判断するというようなことではないかと思います。 一方、その逆の解釈、すなわち、ゼロ割が生じるようなプログラムはそれがどのような局面でさえ、絶対に動作しない、どんな言語、どんな処理系でもこれが生じたらそのシステムは異常終了するのである、というものです。この場合、このアルゴリズムは何が何でも排除しなければならないわけです。 数千行程度のプログラムのバグフィックスをおこなっており、最初の質問に示したような趣旨のアルゴリズムを見つけました。この箇所こそその元凶であると特定したかったのですが、必ずしもそういうことではないということのようですね。もちろん、私がこのアルゴリズムを積極的に採用したいと思っている訳ではありません。私が期待した回答は後者、すなわち絶対回避せよ、なのです。
- gyrocompas
- ベストアンサー率23% (24/104)
前出の回答のように除数の0チェックをするのが定石です。 また、被除数、除数が整数の場合は単純な0チェックで良いですが 浮動小数点の場合は、除数の範囲チェックをする方が望ましいです。 範囲の大きさは、プログラムの仕様とか 想定される商の数値から妥当な範囲を決めるしかないでしょう
- buriburi3
- ベストアンサー率44% (353/792)
どんな処理系を想定しているのか不明ですが、 大抵の処理系では0除算を実行すると除算例外またはオーバーフロー例外が発生して処理の継続が出来なくなります。 0除算は実行自体を回避すべきで除算実行前に分母の値をテストするのが普通です。
お礼
回答有り難うございます。 私も同感です。ゼロ割問題のフォローが計算の後だったら絶対にダメなのでしょうか。私の希望はこのアルゴリズムの完全否定です。処理系や言語にかかわらず、可能性としての否定ではなく、完全否定です。