IEEE在Haskell中的浮点信号NaN(sNaN) [英] IEEE floating point signalling NaN (sNaN) in Haskell

查看:182
本文介绍了IEEE在Haskell中的浮点信号NaN(sNaN)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么方法可以在Haskell中定义信号NaN?我发现了两种处理NaN的方法:
$ b $ 1 1)使用0/0,这会产生相当多的

2)包 Data.Number.Transfinite ,它没有信号NaNs。

有没有什么办法可以把Word64一点一点地放进Double而不用编写C库?


  { - #LANGUAGE ForeignFunctionInterface 

# - }
import Data.Word(Word64,Word32)
import Unsafe.Coerce
import Foreign
import Foreign.C.Types
foreign import ccallfenv。 h feenableexcept - GNU扩展
enableexcept :: CInt - > IO()

类HasNAN a其中
signalingNaN :: a
quietNaN :: a

实例HasNAN Double其中
signalingNaN = unsafeCoerce (0x7ff4000000000000 :: Word64)
quietNaN = unsafeCoerce(0x7ff8000000000000 :: Word64)

实例HasNAN Float其中
signalingNaN = unsafeCoerce(0x7fa00000 :: Word32)
quietNaN = unsafeCoerce(0x7fc00000 :: Word32)

main = do
enableexcept 1 - 我系统中的FE_INVALID
print $ show $ 1 +(quietNaN :: Float) - works
print $ show $ 1 +(signalingNaN :: Float) - 失败

完全失败。原来,FPU异常对于Haskell来说是一个坏主意。由于很好的原因,它们被默认禁用。如果你在gdb中调试C / C ++ /其他东西,那么它们是可以的。我不想调试Haskell核心转储由于其非必要的性质。启用 FE_INVALID 异常会导致0/0,并添加到 Data.Number.Transfinite 中的NaN中。 GHC.Real 崩溃。但在enableexcept之前计算的0/0不会产生异常。



我会在我的任务中使用一些简单的错误检查。我只需要一个地方就需要 sNaN


Is there any way to define signaling NaN in Haskell? I found two approaches to deal with NaNs:

1) use 0/0, which produces quite nan

2) package Data.Number.Transfinite, which has no signaling NaNs too.

PS Is there any way to put Word64 bit by bit into Double without writing C library?

解决方案

I have found one non-portable way:

{-# 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

which perfectly fails. It turned out that FPU exceptions are a bad idea for Haskell. They are disabled by default for a good reason. They are OK if you debug C/C++/something else in gdb. I don't want to debug Haskell core dumps due to its non-imperative nature. Enabling FE_INVALID exceptions causes 0/0 and add to NaNs in Data.Number.Transfinite and GHC.Real to crash. But 0/0 calculated before enableexcept doesn't produce exceptions in addition.

I will use some simple errors check in my task. I need sNaN in just one place.

这篇关于IEEE在Haskell中的浮点信号NaN(sNaN)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆