単位球上の点を見つけるコードが少しあります。単位球について次のことを思い出してください。
1 = sqrt( x^2 + y^2 + z^2 )
アルゴリズムは、0 と 1 の間の 2 つのランダムな点 (x 座標と y 座標) を選択します。それらの大きさが 1 未満である場合、z について上記の方程式を解くことによって 3 番目の座標を定義する余地があります。
void pointOnSphere(double *point){
double x, y;
do {
x = 2*randf() - 1;
y = 2*randf() - 1;
} while (x*x + y*y > 1);
double mag = sqrt(fabs(1 - x*x - y*y));
point[0] = 2*(x*mag);
point[1] = 2*(y*mag);
point[2] = 1 - 2*(mag*mag);
}
技術的には、このコードを継承しました。前の所有者は、「厳格な標準準拠を無視する」-Ofast を使用してコンパイルしました。TL;DR は、コードが厳密な IEEE 標準に従う必要がないことを意味します。そのため、最適化せずにコンパイルしようとすると、エラーが発生しました。
undefined reference to `sqrt'
IEEE 規格とは何ですか? コンピュータは浮動小数点数を無限の精度で格納できないため、注意しないと特定の計算中に丸め誤差が発生します。
グーグルで調べた後、この質問に出くわし、適切なIEEEのものを使用することについて正しい方向に進みました。浮動小数点数に関するこの記事も読みました (これをお勧めします)。残念ながら、それは私の質問に答えませんでした。
Newton Iterationのようなものとは対照的に、関数で sqrt() を使用したいと思います。私のアルゴリズムの問題は、おそらく(実際にはそうではありませんが)負の数を sqrt() 関数に渡す可能性があるという事実に起因することを理解しています。問題を解決する方法がよくわかりません。助けてくれてありがとう!
ああ、それが関連している場合は、Mersenne Twister数ジェネレーターを使用しています。
明確にするために、libm を -lm でリンクしています! また、正しいライブラリを指していることも確認しました。