我发现自己遇到的情况是等待floor $ 1/0
正在执行。
λ> 1/0
Infinity
据我所知,这是正常行为,但Infinity
为floor
'd或ceiling
'd
λ> floor $ 1/0
179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216
而不是失败,产生了这么大的数字。的 为什么?
也许更重要的是,在应用其他功能之前,如何在不使用过滤器的情况下将其与非故障结果区分开来?
答案 0 :(得分:9)
第一个问题可能不那么重要,所以我会先尝试回答第二个问题。
如果您有一个号码,如果您知道它来自floor x
,则无法知道x
是2^1024
的有效表示还是无穷大。你可以假设任何超出double范围之外的东西是无效的,并且是由无穷大,负无穷大,NaN等产生的。使用RealFloat
中的一个/多个函数(例如isNaN
,isInfinite
等)检查您的值是否有效非常简单。
您还可以使用data Number a = N a | PosInf | NegInf
之类的内容。然后你写:
instance RealFrac a => RealFrac (Number a) where
...
floor (N n) = floor n
floor PosInf = error "Floor of positive infinity"
floor NegInf = error "Floor of negative infinity"
..
哪种方法最好主要基于您的用例。
将floor (1/0)
作为错误可能是正确的。但无论如何,价值都是垃圾。处理垃圾或错误更好吗?
但为什么2^1024
?我看了GHC.Float
的来源:
properFraction (F# x#)
= case decodeFloat_Int# x# of
(# m#, n# #) ->
let m = I# m#
n = I# n#
in
if n >= 0
then (fromIntegral m * (2 ^ n), 0.0)
else let i = if m >= 0 then m `shiftR` negate n
else negate (negate m `shiftR` negate n)
f = m - (i `shiftL` negate n)
in (fromIntegral i, encodeFloat (fromIntegral f) n)
floor x = case properFraction x of
(n,r) -> if r < 0.0 then n - 1 else n
请注意decodeFloat_Int#
返回尾数和指数。根据{{3}}:
因此表示正无穷大和无穷大:符号= 0表示 正无穷大,1为负无穷大。偏向指数=全1 位。分数=全0位。
对于Float
,这意味着2 ^ 23的基数,因为基数中有23位,指数为105(为什么105?我实际上不知道。我认为它应该是255 - 127 = 128,但实际上似乎是128 - 23)。 floor
的值为fromIntegral m * (2 ^ n)
或base*(2^exponent) == 2^23 * 2^105 == 2^128
。对于double,此值为1024。