当前位置:  开发笔记 > 编程语言 > 正文

Haskell将(0/0)设置为qnan

如何解决《Haskell将(0/0)设置为qnan》经验,为你挑选了1个好方法。

我注意到Haskell(来自Windows上的Haskell平台的ghci 7.10.2)(0/0 :: Double)从我在C++中看到的QNAN标志上翻了一遍(测试了MSVS C++ 2013和cygwin gcc 4.9.2).Haskell 0xfff8000000000000为(0/0)生成位模式(和 - (0/0)生成0x7ff8 ...).这是C++实现的后退似乎.

这是一个测试程序来说明:

import Data.Word
import Unsafe.Coerce
import Text.Printf

dblToBits :: Double -> Word64
dblToBits = unsafeCoerce

test :: Double -> IO ()
test d = putStrLn $ printf "%12f       0x%x" d (dblToBits d)

go = do
  test (0/0)
  test (-(0/0))
  test (1/0)
  test (-(1/0))

这给出了输出:

      NaN       0xfff8000000000000  <- I expect 0x7F...?
      NaN       0x7ff8000000000000  <- I expect 0xFF...?
 Infinity       0x7ff0000000000000
-Infinity       0xfff0000000000000

请注意,无穷大可以正常运行,但NaN似乎翻了.

这是Haskell中NaN未定义语义的一部分吗?即(0/0)意味着ghc可以使用他们想要的任何NaN模式?那么我们在Haskell中有一个精确的方法是在浮点指定QNAN或SNAN而不依赖于特殊的IEEE库4吗?我正在为一块硬件编写一个汇编程序,可能对它的NaN味道很挑剔.

我被焚烧了unsafeCoerce吗?我在Haskell中没有简单的方法可以将浮点数转换为位数和返回数.

参考文献:

    MSVS 2013. std::numeric_limits::quiet_NaN()中的C++ 给出0x7ff8000000000000.还在cygwin gcc 4.9.2上进行了测试

    std :: numeric_limits :: quiet_NaN.表示符号位的任何含义是实现定义的状态.Haskell对此有类似的规则吗?

    Perl语义与MSV C++一致

    可能的IEEE Haskell 库

    稍微相关的问题使用了unsafeCoerce我回归的同样的无意义.

Dietrich Epp.. 5

你从你的NaN那里问了太多.根据IEEE标准,NaN上的符号位可以是任何东西.因此编译器,处理器或浮点库可以自由地做出他们想要的任何选择,并且您将在不同的编译器,处理器和库上获得不同的结果.

特别是,对于这样的程序,常量折叠可能意味着操作由编译器而不是在目标环境中执行,具体取决于编译器的运行方式.编译器可以使用本机浮点指令,也可以使用GMP或MPFR之类的东西.这并不罕见.由于IEEE标准对符号位没有任何说明,因此对于不同的实现,您将最终得到不同的值.如果您能够在开启或关闭优化时证明值已更改,并且包括类似内容,那么我不会感到完全惊讶-ffast-math.

作为优化的一个例子,编译器知道你正在计算a NaN,并且可能决定不打扰之后翻转符号位.这一切都通过不断传播发生.另一个编译器不会进行这种分析,因此它会发出一个指令来翻转符号位,而那些制作处理器的人不会使该操作对NaN的行为有所不同.

简而言之,不要试图理解NaN上的符号位.

你究竟想在这里完成什么?



1> Dietrich Epp..:

你从你的NaN那里问了太多.根据IEEE标准,NaN上的符号位可以是任何东西.因此编译器,处理器或浮点库可以自由地做出他们想要的任何选择,并且您将在不同的编译器,处理器和库上获得不同的结果.

特别是,对于这样的程序,常量折叠可能意味着操作由编译器而不是在目标环境中执行,具体取决于编译器的运行方式.编译器可以使用本机浮点指令,也可以使用GMP或MPFR之类的东西.这并不罕见.由于IEEE标准对符号位没有任何说明,因此对于不同的实现,您将最终得到不同的值.如果您能够在开启或关闭优化时证明值已更改,并且包括类似内容,那么我不会感到完全惊讶-ffast-math.

作为优化的一个例子,编译器知道你正在计算a NaN,并且可能决定不打扰之后翻转符号位.这一切都通过不断传播发生.另一个编译器不会进行这种分析,因此它会发出一个指令来翻转符号位,而那些制作处理器的人不会使该操作对NaN的行为有所不同.

简而言之,不要试图理解NaN上的符号位.

你究竟想在这里完成什么?

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有