如何在双变量中检查 inf(和 | 或)NaN

Posted

技术标签:

【中文标题】如何在双变量中检查 inf(和 | 或)NaN【英文标题】:How to check for inf (and | or) NaN in a double variable 【发布时间】:2010-11-04 09:35:39 【问题描述】:

考虑以下代码:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

template<class T>
bool IsNaN(T t)

    return t != t;


int main(int argc, char**argv)

    double d1, d2;
    sscanf(argv[1], "%f", &d1);
    sscanf(argv[2], "%f", &d2);

    double dRes = d1/d2;

    cout << "dRes = " << dRes << "\n";

    if(IsNaN(dRes))
        cout << "Is NaN\n";
    else
        cout << "Not NaN\n";


几个问题:

    当我将 0 和 0 作为参数传递时,它会输出 dRes = inf。但我期待dRes = NaN 或类似的东西。 NaN 可以用双变量表示吗?就此而言,任何变量? 当我将 d1,d2,dRes 的数据类型更改为 int 并传递 0 和 0 时,我得到了一个Floating exception。有什么区别? 如何检查变量的值是否等于inf

【问题讨论】:

【参考方案1】:

    使用scanf() 时,double 应使用%lf 而不是%f 读取。 %f 会将输入转换为 32 位 float,因此变量的前 32 位将填充一些无效数据,而后 32 位将作为垃圾保留。

    是的。 #include &lt;limits&gt;,then std::numeric_limits&lt;double&gt;::quiet_NaN()。一些编译器(例如 gcc)也提供了NAN macro in &lt;cmath&gt;

    整数类型没有 NaN 或无穷大。整数除以零会导致an exception (SIGFPE)。

    #include &lt;cmath&gt;,然后是std::isinf(x)。使用 std::isfinite(x) 确保 x 不是 NaN 或 Infinity。

【讨论】:

整数除法和浮点除法的行为不同,因为整数除法是在硬件中完成的,而浮点除法不是?还是别的什么? @nakiya:不,浮点除法也是在硬件中完成的。不同之处在于无穷大不能用int 表示。 在此基础上,有没有办法从整数除以 0 中恢复? (除了预先检查值 - 我不能这样做,因为我无法控制该代码)。 @nakiya:你需要捕获 SIGFPE 信号,这实现起来相当复杂。 :(。是这样的。我们有一个脚本语言,支持基本的算术运算。唯一的问题是,它不检查除数是否为0。不能触摸库代码atm。输入系统也是人为设计的,因此我们无法轻松检查是否将 0 值作为除数传递。对于浮点值,如您所说,这是可以的。但是,整数有问题。【参考方案2】:

函数fpclassify 可以让您检查所有特殊情况的浮点值。

自 C99 以来,它在 &lt;math.h&gt; 中作为宏,在 &lt;cmath&gt; 中作为函数族,对于 floatdoublelong double,在 C++ 之后的重载名称 std::fpclassify 下11.

cppreference 有a nice example

【讨论】:

【参考方案3】:

就那样做吧:

if (dRes  == +1.0/0.0 || dRes  == -1.0/0.0) ... //+INF, -INF
if (dRes  == +0.0/0.0 ) ... //+NaN; i.e. pow(2.0 ,16384.0)

【讨论】:

如果dRes 是一个NaN,那么即使dRes == dRes 也是假的。这一事实创造了一种检查 NaN 的新方法,但这也意味着您的检查完全被破坏了。

以上是关于如何在双变量中检查 inf(和 | 或)NaN的主要内容,如果未能解决你的问题,请参考以下文章

[记] C语言中的nan和inf

如果遇到非有限值(NA、NaN 或 Inf),如何强制出错

运行MATLAB算法程序时报错SVD 的输入不能包含 NaN 或 Inf,求大神指导

IEEE754 浮点数系统中的 NaN 和 +-INF

如何在 Perl 中创建或测试 NaN 或无穷大?

如何检查 AVX 内在 __m256 的 inf