我有一些代码可以在单位球上找到一个点。回想一下,对于单位领域:
1 = sqrt(x ^ 2 + y ^ 2 + z ^ 2)
算法选择0和1之间的两个随机点(x和y坐标)。如果它们的幅度小于1,我们就可以通过求解z的上述等式来定义第三个坐标。
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标准?好吧,因为计算机不能将浮点数存储到无限精度,如果你不小心,在某些计算过程中会出现舍入错误。
经过一些谷歌搜索后,我遇到了this question,这使我在正确的轨道上使用了正确的IEEE内容。我甚至阅读了关于浮点数的this article(我推荐)。不幸的是,它没有回答我的问题。
我想在我的函数中使用sqrt()而不是Newton Iteration之类的东西。我理解我的算法中的问题可能来自我可能(尽管不是真的)将负数传递给sqrt()函数的事实。我不太确定如何解决这个问题。谢谢你的帮助!
哦,如果相关,我使用的是Mersenne Twister数字生成器。
只是为了澄清,我正在将libm与-lm连接起来!我也确认它指的是正确的库。
答案 0 :(得分:1)
对于sqrt
的未定义引用,您需要与libm
相关联,通常使用-lm
或类似选项。
另请注意
如果它们的幅度小于1,我们就可以通过求解z的上述等式来定义第三个坐标。
错了。 x和y必须满足x * x + y * y <= 1才能得到z的解。
答案 1 :(得分:0)
为了确保点满足条件,测试条件本身作为while
循环的一部分,而不是条件的推导。
// functions like `sqrt(), hypot()` benefit with declaration before use
// and without it may generate "undefined reference to `sqrt'"
// Some functions like `sqrt()` are understood and optimized out by a smart compiler.
// Still, best to always declare them.
#include <math.h>
void pointOnSphere(double *point){
double x, y, z;
do {
x = 2*randf() - 1;
y = 2*randf() - 1;
double zz = 1.0 - hypot(x,y);
if (zz < 0.) continue; // On rare negative values due to imprecision
z = sqrt(zz);
if (rand()%2) z = -z; // Flip z half the time
} while (x*x + y*y + z*z > 1); // Must meet this condition
point[0] = x;
point[1] = y;
point[2] = z;
}
答案 2 :(得分:0)
theta = randf()*M_PI;
phi = randf()*2*M_PI;
r = 1.0;
x = r*sin(theta)*cos(phi);
y = r*sin(theta)*sin(phi);
z = r*cos(theta);