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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4095337/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:52:58  来源:igfitidea点击:

How to check for inf (and | or) NaN in a double variable

c++linuxfloating-pointg++

提问by nakiya

Consider the following code:

考虑以下代码:

#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";

}

Couple of questions:

几个问题:

  1. When I pass 0 and 0 as arguments, it outputs dRes = inf. But I was expecting dRes = NaNor something like that.
  2. Is NaN representable in double variables? For that matter, any variable?
  3. When I changed the data type of d1,d2,dRes to int and passed 0 and 0, I got a Floating exception. What is the difference?
  4. How to check if a variable's value is equal to inf?
  1. 当我将 0 和 0 作为参数传递时,它输出dRes = inf. 但我在期待dRes = NaN或类似的东西。
  2. NaN 可以用双变量表示吗?就此而言,任何变量?
  3. 当我将 d1,d2,dRes 的数据类型更改为 int 并传递 0 和 0 时,我得到了一个Floating exception. 有什么不同?
  4. 如何检查变量的值是否等于inf

采纳答案by kennytm

  1. When using scanf()doubleshould be read using %lf, not %f. %fwill convert the input into a 32-bit float, so the first 32 bits of your variables will be filled with some invalid data, and the last 32 bits will be left as garbage.

  2. Yes. #include <limits>, then std::numeric_limits<double>::quiet_NaN(). Some compilers (e.g. gcc) also provides the NANmacro in <cmath>.

  3. There is no NaN or infinity for integer types. Divide-by-zero for integer will cause an exception (SIGFPE).

  4. #include <cmath>, then std::isinf(x). Use std::isfinite(x)to ensure xis not NaN or Infinity.

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

  2. 是的。#include <limits>那么std::numeric_limits<double>::quiet_NaN()。一些编译器(例如GCC)也提供了NAN<cmath>

  3. 整数类型没有 NaN 或无穷大。整数除以零将导致异常 (SIGFPE)

  4. #include <cmath>,那么std::isinf(x)。使用std::isfinite(x),以确保x不NAN或无穷大。

回答by user9137229

Just do it like that:

就这样做:

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)

回答by Ben Voigt

The function fpclassifywill let you inspect a floating-point value for all the special cases.

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

It's found in <math.h>as a macro since C99, and in <cmath>as a family of functions, for float, double, and long doubleunder the overloaded name std::fpclassifysince C++11.

它的发现<math.h>为自C99宏,并<cmath>作为家庭的功能,floatdouble,和long double重载的名义下std::fpclassify,因为C ++ 11。

cppreference has a nice example

cppreference 有一个很好的例子