我发现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
?这样的结果没有数学上的理由。你知道原因吗?
答案 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
巧合的是,如果你想知道当你的实际操作没有引用它们时Integer
和Double
是有问题的类型,请看看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 =-∞这是有道理的。