2013-08-08 9 views
11

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

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

何が起こっているのですか?上記のすべてのケースでZeroDivisionErrorを受け取ってはいけませんか?

更新 "Infinity"は標準データ型ですか?

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

フロートはintsと同じではありません。既に問題を列挙しているようです。 NaNやInfinityのようなものは浮動小数点の典型です。 –

+0

@DaveNewtonしかし、浮動小数点数の場合には例外はありませんが、なぜこの場合ですか? – ZX12R

+0

浮動小数点演算を処理する場合は例外ではないため、明確な値(「無限大」または「NaN」)があります。 Geneのリンクからhttps://en.wikipedia.org/wiki/IEEE_floating_point#Exception_handlingを参照してください。 –

答えて

10

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の標準的な答えは "Not a Number"で、もう一つの浮動小数点定数であるNaNがあります。

定数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 

をこのようにして浮動小数点計算することができますいつでもそれはあふれているか0で割っても合理的な有益な答えを生み出しています(あなたが標準を良く知っていれば、答えに頼っているのは悪い考えです)。

これは、標準が提供する唯一の動作とは異なります。他のものを選択することができます。しかしRubyはこれをあなたのために行います。ソースファイルnumeric.c、関数Init_Numericは、ゼロ除算が無限大になるようにホストプロセッサを設定します。他の言語では、例外を生成するなど、他の選択肢があります。

+7

私は実際の情報を単なるリンクではなく回答に含めることをお勧めします。 –

+0

Um。ごめんなさい。情報はIEEE 754規格を追跡しているということです。すべてのプログラマーは、この標準を十分に認識していなければなりません。私がここでスニペットを引用すると、読者はその機会を逃すでしょう。 – Gene

+4

しかし、リンクのみの回答は本当に大丈夫です。実際の質問を説明するのに必要な2つの文章を表示するためには、すべてを自分自身で読む必要があります。代わりに、サーフェスレベルを超えて理解する必要性を強調し、*と*は特定の質問に答えます。 –

7

フローティングポイントに対する挙動はIEEE 754における標準を反映:

  • 無効演算(負の数の、例えば、平方根)(デフォルトではqNaNを返します)。
  • ゼロ除算(有限オペランドの演算は、正確に無限大の結果を返します。たとえば、1/0またはlog(0))(デフォルトでは±無限を返します)。

ゼロによる整数除算の実行時エラーを実装するための決定は、Java、C++、Pythonなどのような他の多くの言語に共通です。 Pythonは実際にはエラーZeroDivisionErrorも呼び出します。

これらの分類と動作の理由から、sawa's answerを参照してください。

4

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

1/0.0 
1.0/0 

1.0/0.0と同じになり、

/への引数がfloatである
1.0/0.0 # => Infinity 
0.0/0.0 # => NaN 

は、Rubyの浮くように他のタイプは、キャスト:それはの場合について説明します。

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

1/0 # => Error 
0/0 # => Error 
関連する問題