0

我现在正在编写一个项目工作,我最近的问题是输出在一段时间后给出 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,最大
  • absstand() 是向量范数,从数学上讲,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 的敬畏。

4

2 回答 2

5

returnif条件失败时,你什么都不做。如果您使用“返回”值,这将导致未定义的行为。

于 2013-11-15T09:07:12.373 回答
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;
}
于 2013-11-15T09:11:00.200 回答