主题:lnx 用四则运算怎样算出来?
外号小雕儿
[专家分:0] 发布于 2007-07-05 18:25:00
诸位高手:
小弟今在一编程中,碰到一这样的问题,感到棘手,望诸位有能力者助我!
板凳
liangbch [专家分:1270] 发布于 2007-07-06 12:39:00
在计算(ln(x)),时,当 x和1的差很大时,迭代非常慢,直接使用泰勒公式不可取,需要做一些预处理,才可以使用泰勒公式。例如:ln(x)=ln(x0 * x1)=ln(x0)+ln(x1),x0:可以通过某种方法求的,x1非常接近于1,这样就可以求得ln(x),此题的关键如何选取x0,使得x0的对数很容易求得,而且x0非常接近于x.
这里提供一个链接(求一些常数的对数,平方根等)http://numbers.computation.free.fr/Constants/constants.html
下面是这个算法的实现方法:
1.通过特殊的方法事先计算出一些小质数的对数,如集合a=
{2,3,5,7,11,13}
2.找出一组分数,形成数组b,使这些分数依次递增并且大致呈等比数列分布,并且这些分数的分子和分母的所有质因数均来自集合a,且任意两个数的比小于d1,d1略大于1, 这些分数的对数很容易算出
例:数组b={ 1,11/10,6/5,13/10,7/5,3/2,8/5,9/5,2,21/10,11/5,12/5,13/5,3,16/5,...49/5,10}
={1,1.1,1.2,1.3,1.4,1.5,1.6,1.8,2,2.1,2.2,2.4,2.6,3,,3.2,...9.8,10)
3。如果求x的对数,可首先将其化为 x1*10^f1的形式,则lg(x)=lg(x1)+f1.
4. 在数组b中,找一个数b[i],使b[i]<x1<b[i+1],令f2=b[i],x1=x2*f2,则lg(x)=lg(x1)+f1= f1+ lg(f2)+ lg(x2),这里x2 一定小于d1,换言之,x2是一个略大于1的数,可以利用泰勒公式求值,且速度很快。
5。如果想得到更高的精度,在利用泰勒公式求x2时,需要计算的项仍然很多,这时可以再建立一个数组c[1..n],使c[n]略大于d1,对于每一个i,c[i+1]/c[i]<d2,d2是一个比d1 更接近1的数,这样 x2= f3 * x3 ,f3为数组c中的某一个元素,lg(x)=f1+lg(f2)+lg(f3)+lg(x3),由于1<x3<d2<d1,故在利用泰勒公式求lg(x3)时,计算的项数将更少。
6。按此思路,为了减少计算量,可以继续做一个数组d,依次类推。但是数组不可以不断增加,一方面增加了存储空间,另一方面,在构建数组d[1..n]时,d[1]>1,d[n]小于dx,dx越小,满足条件(数组各个元素可以用分数表示,分数的分子分母的所有质因数均为小质数,且分子分母不不能超过计算机中整数的表示范围)的数组元素越少。
7。在查表时,可以使用2分查找算法,如果想进一步提高速度,也可以使用公式法,由一个数x 直接计算出数组下标
利用这个算法可以将某一个数的对数计算到很高精度,且速度很快,这是我在编写超级计算器时,经过长时间的独立思考而得到的一个算法,本算法首次公开于 2004-03-15 公布于csdn。