一个简单的log2(x)的快速计算方法

最近因为某一些原因,需要要求高速计算一下常用对数的值。但是自然对数的快速算法和常用对数的快速算法都没想到......只得去找那个以2为底的对数值的快速运算方法了,由于精度要求不高(大约0.1即可),固可以尝试这种方案。

因为直接把float数据按照整数来读取,得到的值大约是满足这个式子:

其中σ是一个无限小的数据,经过推导值大约是0.0450466,但是这个只是理论。实际却并非如此,我尝试出来的这个值大约是0.0719附近。

#define POW223    8388608.0             // 2^23
double __log2(float x)
{
    long *a;
    double o;
    a = (long*)&x;                      // 强制的位转换
    o = (double)*a;
    // ???实际证明那个0.04几的值误差非常大....
    o = o / POW223 - 126.928071372;
    return o;
}

我测试了[1, 2000]上的所有正整数,其值误差都在0.1以内:

int main()
{
    int i;
    for (i = 1; i <= 2000; i++)
    {
        double diff;
        diff = log2(i) - __log2(i);
        printf("%.10lf\n", diff);
    }

    return 0;
}

选出几个作为对照如下表。其中最右边的是上面函数的输出值,中间是参考的标准值。

数据 参考值 函数运算结果
1155.0f 10.1736774445 10.1998583155
4.0f 2.0000000000 2.0719286280
0.05f -4.3219280243 -4.3280713482

可以看到,数据在较小的值时,该算法会更精确。对(0, 1]范围内,以0.01为步长进行测试,该算法的误差平方和的均值大约为0.000934。因而该算法具有一定的实用性,可进行小范围的对数运算。

第一次写博客呢!不足的地方希望大家多多谅解,更希望稍花几秒,指出错误。

你可能感兴趣的:(杂七杂八)