Ale*_*mov 8 floating-point haskell ieee-754
有没有办法在Haskell中定义信令NaN?我找到了两种处理NaN的方法:
1)使用0/0,产生相当的纳米
2)包Data.Number.Transfinite,它也没有信令NaN.
PS有没有办法在没有编写C库的情况下将Word64逐位放入Double中?
我找到了一种非便携式方式:
{-# LANGUAGE ForeignFunctionInterface #-}
import Data.Word (Word64, Word32)
import Unsafe.Coerce
import Foreign
import Foreign.C.Types
foreign import ccall "fenv.h feenableexcept" -- GNU extension
enableexcept :: CInt -> IO ()
class HasNAN a where
signalingNaN :: a
quietNaN :: a
instance HasNAN Double where
signalingNaN = unsafeCoerce (0x7ff4000000000000::Word64)
quietNaN = unsafeCoerce (0x7ff8000000000000::Word64)
instance HasNAN Float where
signalingNaN = unsafeCoerce (0x7fa00000::Word32)
quietNaN = unsafeCoerce (0x7fc00000::Word32)
main = do
enableexcept 1 -- FE_INVALID in my system
print $ show $ 1 + (quietNaN :: Float) -- works
print $ show $ 1 + (signalingNaN :: Float) -- fails
Run Code Online (Sandbox Code Playgroud)
这完全失败了。事实证明,FPU 异常对于 Haskell 来说是一个坏主意。默认情况下它们被禁用是有充分理由的。如果您在 gdb 中调试 C/C++/其他内容,它们是可以的。我不想调试 Haskell 核心转储,因为它是非命令性的。启用FE_INVALID
异常会导致 0/0 并添加到Data.Number.Transfinite
和中的 NaN 中GHC.Real
导致崩溃。但在enableexcept之前计算的0/0不会另外产生异常。
我将在我的任务中使用一些简单的错误检查。我sNaN
只需要在一个地方。