私は現在、プロジェクト作業をコーディングしています。私の最新の問題は、しばらくすると出力が 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]-Array であり、そのコンポーネントの範囲はおおよそ -5 から 5 で、最大
- abstand() は数学的に言えばベクトルのノルムであり、abstand(dummyd) は 0.6 から 2.5 の間です
- 距離範囲は 2.4 ~ 5.6
- mypow() は、パフォーマンスのための単なるカスタム pow() です
- 3.と9.は数字XP
- 使用される変数はすべて long double です
さらに、関数の最初の項 (下の行long double ret
) をコメントアウトすると、NaN が停止するように見えますが、2 番目の項 (その次の行、長い方) は機能しているようです。
上記の関数は、合計で数百万回繰り返されるアルゴリズム全体の一部です。どこかで、(この関数を使用する) 位置配列と運動量配列の出力が NaN のみを取得し始め、そこから保持されます。出力を実際にフィルタリングするのはかなりの作業ですが、これまでのところ、通常の値 (つまり、予想される範囲内であり、大きな数値には程遠い) から到達しているようです。
ここで、この場合に NaN が発生する理由と、それを修正する方法を理解したいと思います。私に説明できる人は誰でも+10の素晴らしさを得る.