C ++意外的NaN

时间:2013-11-15 09:02:08

标签: c++

我正在编写一个项目工作,我最近的问题是输出在一段时间后给出了NaN(当然是持续的),但由于我的知识有限,我无法弄清楚为什么。我读了一下NaN通常来自哪里(0/0,inf * 0等),但这似乎不是这里的情况。虽然整个代码太长且太复杂而无法在此处发布,但我已经确定了它似乎来自的代码部分:

long double force_dipol(particle &part1, particle &part2, long double distance) {
    if ((abstand(part1.dummyd)!=0) && (abstand(part2.dummyd)!=0) { //Division checks
        long double ret;
        ret = 3.*( part1.dummyd[0]*part2.dummyd[0] + part1.dummyd[1]*part2.dummyd[1] + part1.dummyd[2]*part2.dummyd[2] ) / mypow(distance, 3);
        ret -= 9.*abstand(part1.dummyd)*abstand(part2.dummyd) / mypow(distance, 3) * (part1.dummyd[2]/abstand(part1.dummyd) * part2.dummyd[2]/abstand(part2.dummyd));
        return ret;
    }
}

对于任何关心的人来说,它是偶极 - 偶极相互作用的力量项(耶,物理!)。

  • 粒子是我的结构,只是将变量保持在一起。
  • dummyd是[3] - 阵列是偶极矩,其成分范围从大约-5到5,最大
  • abstand()是向量范数,从数学上讲,abstand(dummyd)介于0.6和2.5之间
  • 距离范围为2.4至5.6
  • mypow()只是为性能定制的pow()
  • 3.和9.是数字XP
  • 使用的所有变量都是long double

此外,如果我注释掉函数的第一个术语(long double ret下面的行),它似乎会停止NaN'ing,而第二个术语(之后的行,更长的一行)似乎可以工作

上述功能是整个算法的一部分,总共迭代了几百万次;沿着这条线的某个地方,位置和动量阵列(使用这个函数)的输出开始只得到NaN并从那里保持它。实际过滤输出是相当多的工作,但到目前为止它似乎从正常值(即在预期的范围内,远远没有大数字)到达。

现在,我想了解为什么在这种情况下我会得到NaN,以及如何解决它。任何可以向我解释的人都会获得+10的惊人效果。

2 个答案:

答案 0 :(得分:5)

return条件失败时,您没有if任何内容。如果您使用“返回”值,这将导致未定义的行为。

答案 1 :(得分:2)

没有返回值是一种可能性,还有mypow()distance为0时做了什么?

0到3 = 0,所以你也有零除(除非mypow()处理)。

尝试:

long double force_dipol(particle &part1, particle &part2, long double distance)
{
  long double ret = 0;
  if ((abstand(part1.dummyd)!=0) && (abstand(part2.dummyd)!=0) && (distance!=0)) //Division checks
  {
    ret = 3.*( part1.dummyd[0]*part2.dummyd[0] + part1.dummyd[1]*part2.dummyd[1] + part1.dummyd[2]*part2.dummyd[2] ) / mypow(distance, 3);
    ret -= 9.*abstand(part1.dummyd)*abstand(part2.dummyd) / mypow(distance, 3) * (part1.dummyd[2]/abstand(part1.dummyd) * part2.dummyd[2]/abstand(part2.dummyd));
  }
  return ret;
}