首页 > 解决方案 > 如果没有那么多 math.h 函数,那么制作对数函数的更简单方法是什么?

问题描述

这个问题我并没有完全帮助我,尽管它给了我一些细节。

我当前的基于代码:

#define e 2.7182818284590452353602874713527

double logarithm(long double dec) {
    // return log10f(dec);
    return result;
}

我从链接的问题中学到了什么:

  1. 对数函数以e为底。由接受的答案表示
  2. 同样通过接受的答案,^不是指数(我打算使这种语法成为指数形式,这可能意味着放弃该power()函数),而是一个 XOR 运算符。
  3. 有人回答了我的问题,但被删除了。这是关于log10f源代码的,但它有点令人困惑,所以对我来说不值得。

现在我对这个函数的标准是它是从头开始制作的,没有多个函数,并且使它成为一个简单的排序(即使我怀疑对数甚至不简单)。

答案代码:

#include <math.h>

float log_num(int num) {
    return log10f(num);
}

是的,相当简单,但作为一个挑战,我不想使用这些log()函数本身,尽管我仍然依赖于<math.h>的函数。

问题:在没有内置对数函数的情况下,从头开始制作对数函数的简单形式是什么?如果不使用<math.h>,那是怎么回事?

标签: cfunctionmathlogarithm

解决方案


如果你需要一些相当准确的东西,你可以使用泰勒级数公式。如果您需要更高的精度,请增加迭代次数。

#define EULER_CONST 2.718281828459045235
#define TAYLOR_ITERATIONS 20

double nat_log(double x) {
    // Trap illegal values
    if (x <= 0) {
        return 0.0/0.0;  // NaN
    }
    
    // Confine x to a sensible range
    int power_adjust = 0;
    while (x > 1.0) {
        x /= EULER_CONST;
        power_adjust++;
    }
    while (x < .25) {
        x *= EULER_CONST;
        power_adjust--;
    }
    
    // Now use the Taylor series to calculate the logarithm
    x -= 1.0;
    double t = 0.0, s = 1.0, z = x;
    for (int k=1; k<=TAYLOR_ITERATIONS; k++) {
        t += z * s / k;
        z *= x;
        s = -s;
    }
    
    // Combine the result with the power_adjust value and return
    return t + power_adjust;
}

推荐阅读