11

ルビーがゼロ除算をどのように処理するかを調べようとしています。Ruby は、クラスに基づいて異なる結果を返します。これは私が試したものです

0/0     # => ZeroDivisionError: divided by 0    
1/0     # => ZeroDivisionError: divided by 0
1.0/0   # => Infinity
0.0/0.0 # => NaN

ここで何が起きてるの?ZeroDivisionError上記のすべてのケースで取得するべきではありませんか?

更新「無限」は標準のデータ型ですか?

(1.0/0).class  # => Float
4

3 に答える 3

11

Ruby はIEEE 754 Floating Point Standardを追跡するだけです。そのウィキペディアのページは、あなたが見ているものをうまく説明しています。多くの現代言語は同じアプローチをとっています。

直感的に、あなたが目にする行動は完全に理にかなっています。一般に、

1/<small number> = <big number>

したがって極限では、

1/0 -> Infinity    and similarly    -1/0 -> -Infinity

Infinity浮動小数点サブシステムが認識する定数です。一方で

0 / <any non-zero> = 0

したがって、0/0 で競合が発生します。ゼロか無限大か?IEEE 標準の答えは「数値ではない」NaNです。ご覧のとおり、もう 1 つの浮動小数点定数です。

定数NaNとプラスまたはマイナスInfinityは、意味のある方法で式を介して伝播します。例えば:

Infinity + <any (necessarly finite) number> = Infinity

<any number> + NaN = NaN

さらに興味深いことに:

1 / Infinity = 0

自分で試すことができるもの:

irb(main):005:0> 1.0 / (1.0 / 0.0)
=> 0.0

このようにして、浮動小数点の計算は、オーバーフローしたり、ゼロで除算したりしても、妥当な情報を提供する答えを生成することができます (ただし、標準を十分に理解した後で、答えに依存することは通常悪い考えであることがわかります)。

これは、標準が提供する唯一の動作ではありません。その他は選択可能です。しかし、Ruby がこれを行います。ソース ファイルnumeric.c、 functionInit_Numericは、ホスト プロセッサを設定して、ゼロによる除算が無限大に伝播するようにします。他の言語では、例外を生成するなど、他の選択が行われる場合があります。

于 2013-08-08T12:07:07.607 に答える
5

ポイントは、float には丸め誤差があることです。float0.0は必ずしも正確なゼロ、または数学的な意味での 0.0 を表しているわけではありませんが、指定さ0.0れた精度に丸められるすべての数値を表しています。正確な 0 による除算は数学的に定義されていませんが、 による除算を禁止する0.0と、除数が に丸められるほど小さいゼロ以外の絶対値を持つ場合にエラーが返される危険があります0.0。除数の絶対値がゼロでないのに小さいときに、プログラムが突然エラーを返すことは望ましくありません。浮動小数点数の場合、除算に特定の数値をシステムに割り当てさせる方が安全です。0.0禁止するのではなく。しかし、その数は通常の方法では表現できないため、NaN または Infinity が割り当てられます。これについて誤解を招くのは、無限は数学的な意味での無限ではないということです。それは単に「このシステムで表現できるどの数よりも大きい数」を意味します。それは次の場合を説明します:

1.0/0.0 # => Infinity
0.0/0.0 # => NaN

への引数の 1 つ/が float の場合、Ruby はもう一方を float に型キャストします。

1/0.0
1.0/0

と同じになり1.0/0.0ます。

一方、整数0は誤差を含まず、正確にゼロなので、そのような危険はありません。ゼロ除算エラーを発生させる方が理にかなっています。それは説明します

1/0 # => Error
0/0 # => Error
于 2013-08-08T12:28:59.180 に答える