【发布时间】:2017-11-02 06:08:16
【问题描述】:
我有一些代码可以在单位球面上找到一个点。回想一下,对于一个单位球体:
1 = sqrt(x^2 + y^2 + z^2)
该算法在零和一之间选择两个随机点(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 链接!我还确认它指向正确的库。
【问题讨论】:
-
-Ofast可能内联了sqrt调用。使用-lm编译(特别是链接),你应该会很好 -
您链接的问题中的this answer 是否无济于事?
-
确保代码首先使用
#include <math.h> -
“算法在零和一之间选择两个随机点(x 和 y 坐标)。”和
x = 2*randf() - 1;不一致。x在[-1 0]之间也可以有负值。 -
你可能认为你正在链接 libm,但它很清楚地告诉你你不是。听听你的编译器。有时会出现问题的一件事是
-lm必须在gcc命令上排在最后。另外,也许编译器和/或库没有安装正确?这里的所有其他东西都是分心的。找到图书馆!