c++ - C++中什么情况下会得到nan?

标签 c++ for-loop nan infinity

我读过一些关于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 中的负无穷大相加。 code> 来自上一次迭代,反之亦然。

但是,尚不清楚为什么您会看到任何输出,因为一旦计数器达到 253(在典型的 C++ 实现中),counter++ 就会变得无效,因为 double 格式缺乏表示 253+1 的精度,因此将 1 加 253 的结果四舍五入为 253 。因此 counter 停止变化,并且循环永远持续下去。

一种可能性是您的编译器正在生成始终终止循环的代码,因为这是 C++ 标准的“前进进度”子句(草案 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 来源的良好指南。

关于c++ - C++中什么情况下会得到nan?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65672894/

相关文章:

c++ - 从标记的姿势相机的姿势

c++ - 如何将两个 cpp 添加到一个 cpp 程序文件

file - Rust:我想获取目录中最后修改的文件

javascript - 在我的猜数游戏中遇到 while 循环问题

for-loop - VBscript 的递归问题

Matlab 将 NaN 插入数组

c++ - 为什么只有指向函数的指针而不是函数的var?

c++ - 使用 protobuf 的段错误

xml - XSL 如何避免 NaN

cluster-analysis - 如何处理插补没有意义的 NaN 值? (PCA)