Ric*_* T. 24 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
Run Code Online (Sandbox Code Playgroud)
我很惊讶地注意到零除以零导致Infinity,而div正确导致异常.A NaN也可以接受/,但为什么Infinity呢?这样的结果没有数学上的理由.你知道原因吗?
Tik*_*vis 41
div不返回的原因Infinity很简单 - Integer类型中没有无穷大的表示.
/返回,Infinity因为它遵循IEEE 754标准(描述浮点数表示),因为默认Fractional类型是Double.其他具有浮点数的语言(例如JavaScript)也会出现此行为.
为了让数学家更加畏缩,如果除以负 0,你会得到不同的结果,尽管-0 == 0浮点数是这样的:
Prelude> 1/(-0)
-Infinity
Run Code Online (Sandbox Code Playgroud)
这也是标准的行为.
如果你使用不同的小数类型Rational,你将得到你期望的行为:
Prelude> 1 / (0 :: Rational)
*** Exception: Ratio.%: zero denominator
Run Code Online (Sandbox Code Playgroud)
巧合的是,如果你想知道为什么Integer和Double在当你的实际操作中没有引用他们问题的类型,看看哈斯克尔如何处理违约类型(特别是数字类型)的报告.
简短的版本是,如果你从Num类中有一个模糊的类型,Haskell将首先尝试Integer然后Double为该类型.您可以使用default (Type1, Type2...)语句更改此设置,也可以使用default ()模块级别的语句将其关闭.
我希望这有帮助:
Prelude> 1/0
Infinity
Prelude> -1/0
-Infinity
Prelude> 0/0
NaN
Run Code Online (Sandbox Code Playgroud)
出于数学原因,这可能不是那种方式.Infinity有时被用作"罪孽箱":在我们的系统中干净利落的所有东西,都放在那里.
例:
Prelude> 10 ** 10 ** 10
Infinity
Run Code Online (Sandbox Code Playgroud)
......绝对不是数学上合理的!