在g ++ 4.4.3上获得负NaN是这个标准吗?

时间:2010-09-22 19:19:44

标签: c++ math gcc floating-point g++

我在Linux上使用Ubuntu Lucid Lynx获得了g ++ 4.4.3,我得到了一个:

-NAN

结果是

。在Hardy Heron上使用g ++ 4.3.1,我得到了所有

这导致我的文本diff回归失败,因为我使用cout来打印这个数值结果。

签名nan的含义是什么?有没有办法告诉编译器无符号的nan是否足够?

3 个答案:

答案 0 :(得分:13)

行为的改变可能是由于库而不是编译器。 glibc肯定会在正确的时间内发生变化 - 从gliderc来源中{2009} 23-25 {25}的ChangeLog.17行进入:

...
     * stdio-common/printf_fp.c: ISO C expects to print the sign of NaN
     as well.
...

答案 1 :(得分:8)

可以得到一个有符号的NaN,因为值的NaN-ness和值的符号由IEEE754中的不同位控制(NaN简单地用特殊的指数值表示,不同于标志位)。尽管如此,我还不知道会采取什么样的行动。

可能生成NaN的正常操作之一可能导致负面变化(如+0/-0+Inf/-Inf)。但我不认为NaN会打印为nan而不管是什么标志。

然而,虽然标准非常详细地详细说明了数字的处理方式,但对于它们的打印方式却非常无声。 Wikipedia page for NaN列出了以下内容:

nan         NaN         NaN%        NAN         NaNQ
NaNS        qNaN        sNaN        1.#SNAN     1.#QNAN
-1.#IND     -NaN        NaN12345    -sNaN12300

其中一些显示标志和额外的有效载荷。

请注意,我在这里谈论的是IEEE标准。 ISO C标准确实指示了有限数量的表单,但是打印的符号和/或有效负载是否依赖于实现。我只能假设库的更高版本改变了他们的行为。

如何在编译器中修复它,我不确定。我只是采取实用的方法,并通过类似sed 's/-nan/nan/g'的方式运行输出文件。希望这不会引入其他问题。

您还应该关注允许打印有效负载的表单,但是当测试再次失败时我只会担心。但我会在sed命令附近的某个地方发表评论,表明它可能会在未来的某个时间发生。这样,至少跟随你的那个人会明白为什么。

答案 2 :(得分:2)

签名NaN是可能的,虽然我对浮点知之甚少,不知道为什么一个平台会产生-NaN而另一个会产生NaN。但是,由于NaN有一些不寻常的行为,我真的不会感到惊讶,那可能发生。

以下是格式化浮点I / O的C99文档描述的片段:

  

表示NaN的双参数   转换为其中一种样式   [ - ] nan或[ - ] nan(n-char-sequence) -   哪种风格,以及任何意义   n-char-sequence,是   实现定义。 F   转换说明符

您可以使用copysign()来获取NaN值的符号。 C99文件中的一个例子:

if (isnan(c)) c = copysign(0.0, c);

但是as paxdiablo indicated,在测试脚本中允许“-nan”结果可能更容易。