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]-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の素晴らしさを得る.

4

2 に答える 2

2

戻り値がないことも 1 つの可能性ですが、0のmypow()場合はどうなりますか?distance

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 に答える