我在Linux上使用Ubuntu Lucid Lynx获得了g ++ 4.4.3,我得到了一个:
-NAN
结果是。在Hardy Heron上使用g ++ 4.3.1,我得到了所有
南
这导致我的文本diff回归失败,因为我使用cout来打印这个数值结果。
签名nan的含义是什么?有没有办法告诉编译器无符号的nan是否足够?
答案 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”结果可能更容易。