tipos real num float convert arithmetic haskell floating-point infinity floor

haskell - real - ¿Por qué el piso infinito no arroja algún error?



real float haskell (1)

La primera pregunta quizás no sea tan importante, así que intentaré responder la segunda pregunta primero.

Una vez que tenga un número, si sabe que proviene del floor x , no puede saber si x fue la representación válida de 2^1024 o si fue infinito. Probablemente pueda asumir que cualquier cosa fuera del rango de doble no es válida y se produjo desde el infinito, el infinito negativo, NaN o similares. Sería bastante sencillo verificar si su valor es válido utilizando una / muchas de las funciones en RealFloat , como isNaN , isInfinite , etc.

También podrías usar algo como data Number a = N a | PosInf | NegInf data Number a = N a | PosInf | NegInf data Number a = N a | PosInf | NegInf . Luego escribes:

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" ..

El mejor enfoque se basa principalmente en su caso de uso.

Tal vez sería correcto que floor (1/0) sea ​​un error. Pero el valor es basura de todos modos. ¿Es mejor lidiar con la basura o un error?

Pero ¿por qué 2^1024 ? GHC.Float un vistazo a la fuente de 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

Tenga en cuenta que decodeFloat_Int# devuelve la mantisa y el exponente. Según wikipedia :

El infinito positivo y negativo se representan así: signo = 0 para infinito positivo, 1 para infinito negativo. exponente sesgado = todos los 1 bits. fracción = todos los 0 bits.

Para Float , esto significa una base de 2 ^ 23, ya que hay 23 bits en la base y un exponente de 105 (¿por qué 105? Realmente no tengo idea. Creo que debería ser 255 - 127 = 128, pero Parece ser en realidad 128-23). El valor de floor es fromIntegral m * (2 ^ n) o base*(2^exponent) == 2^23 * 2^105 == 2^128 . Para el doble este valor es 1024.

Me encontré con un caso en el que se estaba ejecutando el equivalente al floor $ 1/0 .

λ> 1/0 Infinity

Por lo que yo entiendo, este es un comportamiento normal, pero cuando Infinity es el floor ''d'' o el ceiling ''d

λ> floor $ 1/0 179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586298239947245938479716304835356329624224137216

En lugar de fallar, se produce este número muy grande. ¿Por qué?

Quizás más importante, ¿cómo puedo distinguir esto de un resultado no defectuoso sin usar un filtro antes de aplicar otra función?