gpt4 book ai didi

C,使用 sqrt 和 math.h 时出现编译问题

转载 作者:行者123 更新时间:2023-11-30 16:47:41 25 4
gpt4 key购买 nike

对于一个类,我需要提交一个使用 math.h 的 sqrt 方法的文件。由于某种原因,除非我使用 -lm 标志将程序链接到我的文件,否则它无法正确编译。该类将在不使用 -lm 标志的情况下编译我的代码,因此我想知道是否有办法在不使用 -lm 标志的情况下完成这项工作。

谢谢

最佳答案

使用 math.h 求数字的平方根有多种方法。有迭代方法,例如牛顿法(及其所有变体,例如牛顿-拉夫森法等)、泰勒级数近似法等。但是有一些非常快速、非常准确的特定实现可以用于查找可用的平方根(或倒数平方根)。

其中一个实现是 Fast Inverse Square Root归因于约翰·卡马克(John Carmack)(有一些争议)。虽然它以原始形式求倒数平方根,但通过倒数求平方根是微不足道的。

这里有两个函数(一个用于float,一个用于double),您可以在没有math.h的情况下实现它们。令人惊奇的是,通过使用特定的浮点常数,您可以在通常在 3-5 次迭代内收敛的函数中实现令人印象深刻的精度。尝试一下:

/** John Carmack's, Fast Inverse Square Root (square-root version).
* generally converges within 3 iterations
* see: https://en.wikipedia.org/wiki/Fast_inverse_square_root
*/
float sqrt_fisr (float x)
{
float tmp, xhalf = 0.5f * x;
size_t n_terms = 10;
union {
float f;
int i;
} u;
u.f = x;
u.i = 0x5f3759df - (u.i >> 1);

u.f *= 1.5f - xhalf * u.f * u.f;
while (n_terms-- && u.f != (tmp = u.f * (1.5f - xhalf * u.f * u.f)))
u.f = tmp;

return 1.0f / u.f;
}

如果需要使用 double 类型,您可以使用以下内容,但注意使用 uint64_t 类型强制使用 64 位整数(在 stdint.h 中找到),

/** John Carmack's Fast Inverse Square Root (square-root double).
* generally converges within 3 iterations
* see: https://en.wikipedia.org/wiki/Fast_inverse_square_root
*/
double sqrtd_fisr (double x)
{
double tmp, xhalf = 0.5d * x;
size_t n_terms = 10;
union {
double d;
uint64_t i;
} u;
u.d = x;
u.i = 0x5fe6eb50c7b537a9 - (u.i >> 1);

u.d *= 1.5d - xhalf * u.d * u.d;
while (n_terms-- && u.d != (tmp = u.d * (1.5d - xhalf * u.d * u.d)))
u.d = tmp;

return 1.0d / u.d;
}

注意:上面的union用于允许以整数形式输入“浮点常量”,并提供了一个简单的方法语法上合法使用相同位(float 时为 32,double 时为 64)作为整数或内存中值的浮点表示,而不使用可能违反严格别名规则的强制转换。

维基百科页面中有一些链接讨论了计算中使用的“魔数(Magic Number)”的发展,读起来相当有趣。

关于C,使用 sqrt 和 math.h 时出现编译问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43246651/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com