C++ C++;在求和后返回NaN
我正在运行以下代码:C++ C++;在求和后返回NaN,c++,nan,trigonometry,C++,Nan,Trigonometry,我正在运行以下代码: double Scos [61][61][61] = {0}; double kdotr; int ik; int howmany [34] = {0}; auto Fs_ = initializer_list<int>({0}); copy(Fs_.begin(), Fs_.end(), Fs); for ( size_t z=0; z<5; ++z ) { for ( s
double Scos [61][61][61] = {0};
double kdotr;
int ik;
int howmany [34] = {0};
auto Fs_ = initializer_list<int>({0});
copy(Fs_.begin(), Fs_.end(), Fs);
for ( size_t z=0; z<5; ++z )
{
for ( size_t y=0; y<5; ++y )
{
for ( size_t x=0; x<10; ++x )
{
for ( int k1=0; k1<=60; ++k1 )
{
for ( int k2=0; k2<=60; ++k2 )
{
for ( int k3=0; k3<=60; ++k3 )
{
int i = x+y*10+z*50;
kdotr = (double)dQ*( (k1-30)*(x_[i][0]-x) + (k2-30)*(x_[i][1]-y) + (k3-30)*(x_[i][2]-z) );
if ( isnan(kdotr) )
cout << "kdotr " << k1 << " " << k2 << " " << k3 << endl;
Scos[k1][k2][k3] += (double)cos(kdotr);
if ( isnan(Scos[k1][k2][k3]) )
cout << "Scos " << k1 << " " << k2 << " " << k3 << endl;
}
}
}
}
}
}
for ( int k1=0; k1<=60; ++k1 )
{
for ( int k2=0; k2<=60; ++k2 )
{
for ( int k3=0; k3<=60; ++k3 )
{
double k = (double)dQ*sqrt( pow((k1-30),2) + pow((k2-30),2) + pow((k3-30),2) );
ik = round(k/0.1);
Fs[ik] += Scos[k1][k2][k3];
if ( isnan(Fs[ik]) )
cout << "Fs[ik] " << k1 << " " << k2 << " " << k3 << endl;
++howmany[ik];
}
}
}
double-Scos[61][61][61]={0};
双kdotr;
int-ik;
int多少[34]={0};
auto Fs_u=初始值设定项_列表({0});
复制(Fs.begin(),Fs.end(),Fs);
对于(size_t z=0;z而言,此类问题总是由计算的某些输入“无效”(导致FPU生成一个NaN作为结果)或将“NaN”本身用作输入引起的
在这种情况下,通过快速扫描您执行的操作,似乎只有一些操作不会基于(例如)负输入生成NaN[如sqrt或log会这样做],因此我的想法是,您的一个或多个输入正在读取未初始化(或未正确初始化)的数据
我将首先检查以下所有组件:
x_[i][0]-x) + (k2-30)*(x_[i][1]-y) + (k3-30)*(x_[i][2]-z
不是NaN
。尤其是x[i][0,1,2]
由于您的代码不是一段完整的可执行代码,而且某些变量的初始化甚至不在代码段中,因此这里的任何人都不可能给您一个精确的答案,说明您的代码哪里出了问题。好的,我让代码在没有NaN的情况下工作
正如一些评论者指出的,初始化可能存在问题。事实上,我没有直接使用Fs
(它是更大类的成员-此代码本身是方法的一部分),而是将余弦和存储在一个临时数组Fs\uu
,在方法内部声明和初始化(例如,像Scos
):现在不再有NaN了。不,这对我来说从来没有发生过。另一方面,我从来没有在另一个循环中有5个for循环。NaN的常见原因是,您的另一个计算使用NaN作为输入(或者进行出错的数学运算,得到NaN)。我怀疑您的一些数据初始化不正确。kdotr从未初始化过?为什么?您应该从Bццц中吸取的一点不是不应该嵌套5个循环,而是复杂的代码很容易出错。如果您有5个嵌套的循环,那么很容易忘记您正在做的事情。例如,代码中还有其他有趣的事情例如,将Fs
与copy
算法结合使用,从一个值中复制出一个值……你想做什么?你能用简单的术语解释一下吗?你能用更小的子问题描述逻辑吗?你能将代码重构成这些子问题,并在将它们混合在一起之前验证每个部分是否工作正常吗是否需要强制转换?@Pippo:确保总和的所有输入都正确,无穷大和NaN不相同。可能是您访问了内存中的错误地址,或者读取的数组没有正确初始化。但是如果kdotr
出现问题,为什么Scos
永远不会被视为NaN?关于可执行文件代码,你说得很对,但是原始代码是一个完整的分子动力学(它非常庞大)。假设这是一台x87机器,那么就不可能有Fs[ik]
可以是NaN,而不是Scos
是NaN,除了实际数据条目的损坏。我会在输入值出错时添加代码来检查输入值。谢谢你,Mats。问题实际上是使用Fs
。相反,使用临时数组Fs
代码工作。我在回答中详细解释了它。是的,因此如果Fs
未正确初始化(例如,包含一个NaN,向其中添加另一个值将导致NaN)。但没有向另一个合法值添加“合法”值(在所选浮点格式的有效范围内)可能会导致NaN溢出,但我怀疑实际情况是否如此。我认为您的Fs
包含不正确的内容。