C,在使用sqrt和math.h时遇到编译问题

时间:2017-04-06 05:46:09

标签: c libraries

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

由于

3 个答案:

答案 0 :(得分:0)

math.h标头声明在库中实现的与-lm链接的函数。如果你不能用-lm链接,那么你就不能使用math.h中的函数。所以,正如@StoryTeller所评论的那样:

  

不要使用math.h

中的功能

答案 1 :(得分:0)

前段时间我遇到了同样的问题,用这些链接器标志进行了很多尝试,其中改变了lib的顺序(这些尝试都没有工作)。所以我刚刚实现了牛顿平方根方法。链接:Square root of a number

使用牛顿法制作立方根或更高级别的根计算函数并不困难。:)

这是简单的原型:

double sqaure_root_of(double value){
double  s1 = 0;
double  q1 = 0;
uint8_t cnt = 0;
uint8_t digit_num = 0;
uint32_t value1 = (uint32_t)value;

while(value1 != 0){
    value1 = value1/10;
    digit_num++;
}
if((value > 0)&&(value < 1)){
    digit_num = 10;
}

if(value <= 0)
    return 0;

s1 = value/2;
printf("s1: %f\r\n",s1);
while(cnt < digit_num*2){
    q1 = s1*s1;
    q1 = q1-value;
    q1 = q1/(2*s1);
    q1 = s1-q1;
    cnt++;
    s1 = q1;
}
return q1;

}

答案 2 :(得分:0)

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

其中一个实施是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,您可以使用以下内容,但 note 使用uint64_t类型强制执行64位整数(在{{1}中找到) }),

stdint.h
{p> 注意:用于允许以整数形式输入“浮点常量”,并为语法提供一种简单的方法合法使用相同的位(在/** 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)作为内存中值的整数或浮点表示而不使用可能与严格别名规则发生冲突的强制转换。

维基百科页面中有链接讨论计算中使用的“幻数”的开发,这是一个非常有趣的阅读。