在什么情况下我们在c ++中得到nan?

In what situation do we get nan in c++?

我读了一些关于 nan 的文章,但网站并未提及所有情况。例如,我编译了这段代码并收到了 nan。 为什么它不给 inf ?

#include <iostream>

using namespace std;

int main()
{
    double input,counter,pow= 1, sum = 0, sign = 1.0;
   
    cin >> input;
    
    for (counter = 1; pow / counter >= 1e-4; counter++)
    {
        pow *= input;
        sum += sign * pow / counter;
        sign = -sign;
    }
    cout << sum << endl;
}

结果是:

nan

输入“2”后,您的程序将两个符号相反的无穷大相加,生成 NaN。发生这种情况是因为重复将 pow 乘以 2 导致它变成无穷大,并且交替 sign 导致正无穷大被添加到 sum 中的负无穷大从上一次迭代或反之亦然相反。

但是,不清楚为什么您会看到任何输出,因为一旦计数器达到 253(在典型的 C++ 实现中),counter++ 就会失效,因为那时 double 格式缺少表示 253+1 的精度,所以将 253 加一的结果四舍五入为 253。所以 counter 停止变化,循环永远继续。

一种可能是您的编译器正在生成始终终止循环的代码,因为 C++ 标准的“Forward progress”子句(草案 n4659 中的 4.7.2)允许这样做。它说编译器可以假设你的循环不会永远继续下去而不做一些有用的事情(比如写输出或调用 exit),这允许编译器生成退出循环的代码,即使它会永远继续输入的“2”。

根据 IEEE-754 标准,产生 NaN 结果的操作包括:

  • 对 NaN 的运算,
  • 零乘以无穷大,
  • 两个同号无穷大相减或两个异号无穷大相加,
  • 零除以零或无穷大除以无穷大,
  • 除数为零或被除数为无穷大时的余数,
  • 小于零的值的平方根,
  • 一些实用程序和数学例程中的各种异常(例如 pow,请参阅 IEEE-754 9.2、5.3.2 和 5.3.3)。

C++ 实现并不总是符合 IEEE-754,但这些通常是 NaN 来源的良好指南。