2016-04-26 45 views
5

我有以下程序:double和NaN的比较结果是什么?

#include <iostream> 
#include <cmath> 

int main() { 
    double a = 1; 
    double b = nan(""); 

    std::cout << (a > b) << std::endl; 
    std::cout << (b > a) << std::endl; 

    return 0; 
} 

输出:

0 
0 

一般从nan意义 - not a number很显然,与nan任何操作基本上是没有意义的。从我在互联网上发现的IEEE-754我发现如果在FPU中至少有一个操作数是nan,结果也是nan,但我没有发现正常值和nan之间的比较,如上例。

标准对此有何评论?

+1

FPU函数和比较的逻辑结果可能是两个不同的东西。你的反汇编说什么? – tadman

+0

您的代码可能(或可能不会)缺少'=='比较。你确实检查了'<' and '>'而不是'=='。也许你打算使用'<' and '> ='或'<=' and '>'。 – jotik

回答

7

标准对此有何评论?

C++标准没有说明如何操作NaNs的行为。它是未指定的。所以,就C++而言,任何结果都是可能的并且是允许的。

ANSI/IEEE标准754-1985说:

5.7。比较

...每个NaN都会将无序与包括它自己在内的所有事物进行比较。 ...什么无序装置恰好被示出在表4中相同的部分

。但简而言之,这意味着如果任何操作数是NaN,那么比较将返回错误,除了!=将返回true。

+0

也许我没有读到它的好处。谢谢! – Alex

1

0这里意味着错误。 Nan不等于或与任何值相当,所以操作的结果是错误的(0)。

+0

你说的非常合乎逻辑,但是你可以在定义它的地方给出任何参考。 – Alex

2

您看到的0意味着false在这种情况下,因为这是默认情况下流显示为false的内容。如果你想看到它作为truefalse使用std::boolalpha

std::cout << std::boolalpha << (a > b) << std::endl; 

乳清比较浮点值,其中值之一是楠则x<yx>yx<=yx>=y,并且x==y都会计算为假,而x!=y将永远是真实的。 Andrew Koenig在Dr Dobbs网站上有一篇关于此的好文章。

当您考虑它时,结果不能为nan,因为比较运算符需要返回一个只能有2个状态的布尔值。

+0

你能否在这个行为定义的地方提供任何引用(我的意思是NaN和任何其他正常值之间的比较操作)? – Alex

+0

@Alex - 我提供了一篇文章链接 – Sean

0

那么,在@ user2079303顶部的相当不错的答案,有两个NaN:安静的NaN和信号NaN。您可以在您的平台上检查std::numeric_limits<T>::has_signaling_NaN是否有信号NaN可用。如果这是真的和值包含std::numeric_limits<T>::signaling_NaN,然后

当NaN被用作参数的算术表达式的信令,适当的浮点异常可以被升高和NaN被“安静”,即,表达式返回一个安静的NaN。

要真正获得FP异常,您可能需要设置FPU控制字(对于x87单元)或MXCSR寄存器(对于SSE2 +单元)。这对于x86/x64平台是正确的,请检查您的平台文档是否具有类似的功能