2013-11-15 38 views
0

我正在编写一个项目工作,我的最新问题是输出NaN后一段时间(然后坚持,当然),但以我有限的知识,我不明白为什么。我读了一些关于NaN通常来自何处的地方(0/0,inf * 0等),但这似乎并不是这种情况。而整个代码过于漫长而复杂,张贴在这里,我已经确定的代码的情况下它似乎来自:C++意外的NaN

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)之间是从2.4到5.6
  • MYPOW()0.6和2.5
  • 距离范围仅仅是出于性能
  • 定制POW()
  • 的3和9是用于数字XP
  • 所有变量都是长双

此外,如果我注释掉函数的第一项(long double ret以下的行),它似乎停止了NaN'ing,而第二项(此后的行,更长的行)似乎工作。

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

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

回答

5

if条件失败时,您不需要return任何东西。如果使用“返回”值,这将导致未定义的行为。

+0

很好的回答。如果OP仍然有问题,那么使用'if'语句来检查结果应该使您能够打印麻烦的输入,并在必要时放置一个断点来调用调试器。 –

+0

+1。我正忙于检查数学,我没想过要检查代码! – parrowdice

+0

@ user2995421出于好奇:您的编译器没有警告您“控制达到非void函数的结束”,还是您忽略了警告? – Hulk

2

没有返回值是一种可能性,但当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; 
} 
+0

不,mypow()不处理任何东西,但距离也不能为0。事实上,我正在养成检查我划分的所有事情的习惯,但这里并不需要。为了好的措施,我复制了代码并尝试了,但问题依然存在。 – user2995421

+0

@ user2995421:“我养成了检查我除以分隔的所有事情的习惯,但在这里它确实没有必要” - 这从来都不是真实的:O,特别是在没有检查/ zero的孤立函数中。如果'mypow'的实现发生更改,则会在代码的其他部分留下潜在的崩溃。最佳做法是使用防御性编程。 – parrowdice