C++意想不到的 NaN

C++ Unexpected NaN

本文关键字:NaN 意想不到 C++      更新时间:2023-10-16

我现在正在编写一个项目作品,我最新的问题是输出在一段时间后给出 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 ret下面的行),它似乎停止了 NaN'ing,而第二个术语(之后的行,较长的行)似乎有效。

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

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

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

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

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;
}