【问题标题】:What does "-nan" mean and what causes it?“-nan”是什么意思,是什么原因造成的?
【发布时间】:2021-07-04 06:23:09
【问题描述】:

我知道nan的意思是“不是数字”,但是这段代码使用高斯消元算法输出“-nan”:

#include <bits/stdc++.h> 
#include <algorithm>

using namespace std;
typedef long long ll;
const int N=55;
const double eps=1e-7;
int n;

struct mat {
    int l,c;
    double p[N][N];
    double* operator [] (int i) {return p[i];}
}a;

bool flo0(double &x) {return (fabs(x)<=eps)?1:0;}

void REF() {
    for(int i=1;i<=n;i++) {
        int flag=i;
        for(int j=i;j<=n;j++) {
            if(fabs(a[j][i])>fabs(a[flag][i])) flag=j;
        }
        for(int j=1;j<=n+1;j++) swap(a[flag][j],a[i][j]);
        if(flo0(a[i][i])) continue;
        for(int j=i+1;j<=n;j++) {
            double t=a[j][i]/a[i][i];
            for(int k=i;k<=n+1;k++) {
                a[j][k]-=t*a[i][k];
            }
        }
    }
}

void RREF() {
    for(int i=n;i>=1;i--) {
        if(flo0(a[i][i])) continue;
        for(int j=n+1;j>=i;j--) a[i][j]/=a[i][i];
        for(int j=i-1;j>=1;j--) {
            double t=a[j][i];
            for(int k=n+1;k>=1;k--) {
                a[j][k]-=t*a[i][k];
            }
        }
    }
    bool no=false,many=false;
    for(int i=1;i<=n;i++) {
        int t=0;
        for(int j=1;j<=n;j++) if(flo0(a[i][j])==false) ++t;
        if(t==0 && flo0(a[i][n+1])==false) no=true;
        if(t==0 && flo0(a[i][n+1])) many=true;
    }
    if(no) printf("-1");
    else if(many) printf("0");
    else for(int i=1;i<=n;i++) {if(flo0(a[i][n+1])) a[i][n+1]=0.0;printf("x%d=%.2lf\n",i,a[i][n+1]);}
}

int main() {
    scanf("%d",&n);
    for(int i=1;i<=n;i++) {
        for(int j=1;j<=n+1;j++) {
            cin>>a[i][j];
        }
    }
    REF();
    RREF();
    
    return 0;
}

我无法获得输入,但输出是

x1=-nan
x2=-nan
x3=-nan
x4=-nan
x5=-nan
x6=-nan
x7=-nan
x8=-nan
x9=-nan
x10=-nan
x11=-nan
x12=-nan
x13=-nan
x14=-nan
x15=-nan
x1...

我最初以为原因是我在确定一个double是否等于0时没有使用“eps”,但我添加后,错误仍然存​​在。 我无法从谷歌获得任何关于“-nan”的信息。

【问题讨论】:

  • 当您使用 Google 搜索 -nan 时,您实际上是在告诉 Google 排除包含 nan 的结果。棘手。如果你知道nan 代表Not a Number,那么用谷歌搜索会更容易,所以这里的“不是数字”是负数。 nan 可能发生,例如一般来说,除以零。
  • 你能提供一个发生这种情况的输入吗?当我使用输入3 1 2 3 4 5 6 7 8 9 1 2 3 运行这个程序时,它会输出x1=0.00 x2=-1.00 x3=2.00。如果相同的输入在您的机器上导致 nan,则您可能在某处有未定义的行为
  • 数组索引从 0 到 N-1。你的循环看起来不像for(int i=1;i&lt;=n;i++),而是for(int i=0;i&lt;n;i++)
  • 旁白:通过自动格式化程序运行您的程序。真的很难看清哪些语句是由哪个ifs 和fors 控制的
  • 另外,您的单字母变量名称会使代码更难理解。然后这个东西:typedef long long ll;——不要有这样的宏。 C++ 中有一个数据类型int64_t,您应该使用它。它显示数据类型以及位宽。然后是试图在 C++ 中伪造基于 1 的数组的明显问题——如果这是整个-nan 问题的根源,即越界,请不要感到惊讶。 C++ 中的数组从 0 开始,而不是 1。

标签: c++ algorithm math floating-point double


【解决方案1】:

这是一个非数字值,其符号位为负数,您的运行时已决定将其显示为“负 nan”。

【讨论】:

  • 感谢您的回答。但是我在所有除法之前判断了分红是否为0,你说的应该没有错,所以我还是一头雾水。
  • @JochiHua 获取 nan 的方式比0./0.多得多
【解决方案2】:

程序运行时,p[i][j] 中的值溢出,得到inf。而inf/inf 导致nan

【讨论】:

    猜你喜欢
    • 2015-01-07
    • 2021-02-24
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-12
    相关资源
    最近更新 更多