在Haskell中除以零

时间:2012-02-19 22:43:59

标签: math haskell division divide-by-zero

我发现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

我很惊讶地注意到小数除以零导致Infinity,而div正确导致异常。 NaN也可以接受/,但为什么Infinity?这样的结果没有数学上的理由。你知道原因吗?

4 个答案:

答案 0 :(得分:41)

div未返回Infinity的原因很简单 - Integer类型中没有无限的表示。

/返回Infinity,因为它遵循IEEE 754标准(描述浮点数表示),因为默认Fractional类型为Double。其他具有浮点数的语言(例如JavaScript)也会出现此行为。

为了让数学家更加畏缩,如果除以负数 0,你会得到不同的结果,尽管浮点数为-0 == 0

Prelude> 1/(-0)
-Infinity

这也是标准的行为。

如果您使用其他小数类型,例如Rational,您将获得所期望的行为:

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

巧合的是,如果你想知道当你的实际操作没有引用它们时IntegerDouble是有问题的类型,请看看Haskell如何处理默认类型(特别是数字类型) )report

简短版本是,如果Num类中有一个含糊不清的类型,Haskell将首先尝试Integer,然后尝试Double。您可以使用default (Type1, Type2...)语句对其进行更改,或者在模块级别使用default ()语句将其关闭。

答案 1 :(得分:6)

我希望这会有所帮助:

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

答案 2 :(得分:5)

出于数学原因,这可能不是那种方式。 Infinity有时被用作“罪孽箱”:在我们的系统中干净利落的所有东西,都放在那里。

示例:

Prelude> 10 ** 10 ** 10
Infinity

......绝对不是数学上合理的!

答案 3 :(得分:3)

小数等于Float(或Double)类型。

1 / n的分数,其中n变为0,因此lim(n→0)1 / n = +∞,lim(n→0)-1 / n =-∞这是有道理的。