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

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

在内存中,float类型是这样存放的:

符号(1)+[指数位+127](7)+底数[23使用,占24],那么换句话说,当直接转换的时候,高位就要变成符号位,然呢,就是低位的处理了:

// x是输入的值
long *a;
float o;
a = (long*)&x;
o = (float)*a;


当上面的代码运行的时候,输出的o的值大约是满足下面这个式子的:

其中σ是一个无限小的数据,经过推倒值大约是0.0450466,但是这个只是理论。实际上,我发现这个值是在0.7几,数据才精确。自然的,由于上面的式子中出现了log2(x),因此可以借助这个方法计算2为底的对数值:

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

在运行中,我分别测试了1155.0f, 4.0f, 0.05f这三个数,其中最右边的是上面函数的输出值,中间是参考的标准值

数据 参考值 函数运算结果
1155.0f 10.1736774445 10.1998596191
4.0f 2.0000000000 2.0719299316
0.05f -4.3219280243 -4.3280715942

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

发布了4 篇原创文章 · 获赞 1 · 访问量 6446

猜你喜欢

转载自blog.csdn.net/YanEast/article/details/78985819