//PI计算javascript程序,Machin+百亿进制优化,2006.12 许剑伟 莆田十中
GJ2_machin={
add:function(a,b,n){ //多精度a对多精度b的相加算法(小学加法)
for(var i=n-1,f=0;i>=0;i--){
a[i]+=b[i]+f;
if(a[i]>=10000000000) a[i]-=10000000000,f=1; else f=0;
}
},
sub0:function(a,b,r,n){ //多精度a对多精度b的相减算法(小学减法)
for(var i=n-1,f=0;i>=0;i--){
r[i]=a[i]-b[i]-f;
if(r[i]<0) r[i]+=10000000000,f=1; else f=0;
}
},
div:function(a,b,n){ //多精度a与单精度b相除算法(小学除法)
for(var i=0,f=0,c;i<n;i++){
c=a[i]+f*10000000000;
a[i]=Math.floor((c+0.1)/b);
f=c%b;
}
},
dao:function(a,f,b,n){ //倒数(f/b)
a[0]=Math.floor(f/b); f=f%b;
for(var i=1,c;i<n;i++){
c=f*10000000000;
a[i]=Math.floor((c+0.1)/b);
f=c%b;
}
},
set:function(a,v,n){ for(var i=0;i<n;i++) a[i]=0; a[0]=v; a.length=n;}, //给数组置0并给首位置初值v
//以下计算圆周率,计算公式:Machin PI=16arctg(1/5)-4arctg(1/239)
a:new Array(),b:new Array(),c:new Array(), //三个工作数组,a存PI,b存arctg,c是临时数组
arctg:function(k,v,zf,N){//求v*arctg(k),zf表示结果累加到a时的正负号
var i=Math.round(N*23.1/Math.log(k*k)),n=i,n2;
var a=this.a, b=this.b, c=this.c;
for(;i>=0;i--){
n2=Math.round((n-i)*N/n)+1; //末项计算位数控制
if(n2>N) n2=N;
this.dao(c, v,2*i+1,n2);
this.div(b, k*k,n2);
this.sub0(c,b,b,n2);
}
this.div(b,k,N);
if(zf>0) this.add(a,b,N);
else this.sub0(a,b,a,N);
},
pi:function(){ //本程序所得最后5位可能有错
var N=GJ2_N.value-0; N=floor(N/10+1.5); //N为计算的位数
var a=this.a, b=this.b; this.set(a,0,N); this.set(b,0,N); //PI结果数组及arctg数组,初值置0
this.arctg(5,16,1,N);
this.arctg(239,4,-1,N);
a[0]='<br>';
for(var i=1;i<N;i++){
a[i]=String(10000000000+a[i]).substr(1,10); //补足10位
if(i%10==0) a[i]+='<br>'; else a[i]+=' ';
}
GJ2_out.innerHTML= '基于Machin公式,并做百亿进制优化,速度较快。<br>'
+'计算公式:Machin PI=16arctg(1/5)-4arctg(1/239)<br>'
+'最后5位可能有错:<font color=red>PI=3.'+a.join('')+'</font>';
}
};
这段程序中,多精度数以十个十进制位(即十亿)为一个单元进行计算的,我想改为以九位十进制数为一个单元时行多精度运算,不知道需要作什么改动,如果不作发运,不知对arctg的结果有没有影响