2012-02-19 6 views
24

div/の動作の間にかなり奇妙な不一致があります。ハスケルでゼロ除算

*ghci> :t 1 `div` 0 
1 `div` 0 :: Integral a => a 
*ghci> :t 1/0 
1/0 :: Fractional a => a 
*ghci> 1/0 
Infinity 
*ghci> 1 `div` 0 
*** Exception: divide by zero 

divが正しく例外につながる一方で私は、ゼロによる分数の割り算はInfinityにつながることに気づくのは非常に驚きました。 /の場合はNaNでも問題はありませんが、なぜInfinity?そのような結果には数学的正当性はない。あなたはこの理由を知っていますか?

+3

「1/0」の結果を「無限大」にすることは数学的に完全に正当化されています。これは唯一の正当な戻り値ではありませんが、最も理にかなったものです。 '1/0 :: Rational'を評価すると、' divide by zero'というエラーも出ることに注意してください。 –

+5

@ダニエルフィッシャー:この種のコンパクト化(正と負の無限大を持つ)はholdを保持するかなり多くの定理を破壊し、それらのいくつかは多くのプログラムで想定されるため、「数学的に完全に正当化された」とは言いません。 – leftaroundabout

+1

浮動小数点数を使って作業するときは、そのようなものを想定するべきではありません。連想性のような基本的な性質さえも必ずしも成立しません。平等は 'NaN'にとっても反射的ではありません! –

答えて

41

divInfinityを返さない理由は、Integerタイプの無限大の表現はありません。

/戻りInfinityデフォルトFractionalタイプDoubleあるので、それは(浮動小数点数の表現を記述する)IEEE 754規格に従うからです。浮動小数点数を持つ他の言語(JavaScriptなど)もこの動作を示します。数学者はもっとうんざりさせるために

あなたは0 で割る場合は、浮動小数点数のため-0 == 0という事実にもかかわらず、異なった結果が得られます。

Prelude> 1/(-0) 
-Infinity 

これは、標準からの動作です。

あなたはRationalなどの異なる分数の種類を使用する場合は、あなたが期待する行動を取得します:あなたがするとき、あなたの実際の動作IntegerDoubleが問題の種類があります理由について迷っている場合は、

偶然
Prelude> 1/(0 :: Rational) 
*** Exception: Ratio.%: zero denominator 

は、それらを参照していない場合、Haskellがreportのデフォルトの型(特に数値型)をどのように扱うかを見てください。

短いバージョンでは、Numクラスのあいまいなタイプの場合、HaskellはまずそのタイプのIntegerを試してからDoubleを試します。これはdefault (Type1, Type2...)ステートメントで変更することも、モジュールレベルでdefault()ステートメントで無効にすることもできます。

+0

ここで 'default'ステートメントについて知ることができますか?これまで見たことがありません – amindfv

+1

私がリンクしているレポートのセクションは、最後に、HaskellのGentle Introductionにも言及していると思いますが、私がここで扱ったよりもはるかに多いとは思えません。(いくつかの拡張を有効にしない限り、数値型に関するもので、 ) –

+0

Prelude> 1 /( - 0) プログラムエラー:{primDivDouble 1.0 0.0} –

6

私はこれが役に立てば幸い:

Prelude> 1/0 
Infinity 
Prelude> -1/0 
-Infinity 
Prelude> 0/0 
NaN 
+0

ありがとうございます。 –

3

端数は入力はfloatに等しい(またはダブル)ではありません。

1/nの分数nが0になるようにlim(n→0)1/n = +∞、lim(n→0)-1/n =-∞となります。

+0

'Fractional'制約は浮動小数点型である' Double'にデフォルト設定されると思います。私がリンクしているレポートのセクションを読んでください。 –

+0

@TikhonJelvisが正しくありません。そうでないと、デフォルトの宣言がない限り、 'Fractional'制約を持つあいまいな型はデフォルトで' Double'になります。 –

5

数学的理由から、そうでないかもしれません。 Infinityは「sin bin」として時々使用されます。私たちのシステムではうまく動作しないものは、そこに入れてください。

例:

Prelude> 10 ** 10 ** 10 
Infinity 

は...確かに数学的に正当化されません!

+1

あなたはまだハードコアのファインティストには出会っていません! :) – Ingo

+0

@Ingoゼロ、1、無限のようなハードコア? –

+0

@ダニエル私は、宇宙にはそれほど多くの物体がないので、10^100のような数字は意味を持たないと言っています。しかしおそらく彼らは10^10^10 = NaN – Ingo