一个简单的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.0f10.173677444510.1998583155
4.0f2.00000000002.0719286280
0.05f-4.3219280243-4.3280713482

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

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值