最近写个关于数值计算的数学软件,是用java语言写的。在书上看到一个关于求代数多项式所有实根和复根的算法。里面有这个一段:
againk:nn=N-k-1;p=0.0;q=0.0; it=0; iterat:it=it+1; ..... b[nn]=a[nn]-p*b[nn-1]-q*b[nn-2]; delta=c[nn-1]*c[nn-1]-(c[nn-1]-b[nn-1])*c[nn-3]; deltap=(b[nn-1]*c[nn-2]-b[nn]*c[nn-3])/delta; deltaq=(b[nn]*c[nn-2]-b[nn-1]*(c[nn-1]-b[nn-1]))/delta; p=p+deltap; q=q+deltaq; delta=sqrt(deltap*deltap+deltaq*deltaq); if( delta > EPSILON ) goto iterat; ..... if( k < N-1 ) goto againk;
我将其翻译成java代码:
do { nn=N-k-1 ; p=0.0 ; q=0.0 ; it=0 ; do { it++ ; ..... b[nn]=a[nn]-p*b[nn-1]-q*b[nn-2] ; delta=c[nn-1]*c[nn-1]-(c[nn-1]-b[nn-1])*c[nn-3] ; deltap=(b[nn-1]*c[nn-2]-b[nn]*c[nn-3])/delta; deltaq=(b[nn]*c[nn-2]-b[nn-1]*(c[nn-1]-b[nn-1]))/delta; p+=deltap ; q+=deltaq ; delta=Math.sqrt(deltap*deltap+deltaq*deltaq) ; }// end while while(delta>EPSILON) ; ..... } //end while while(k<N-1) ;
两个C语言中的goto语句,我翻译成do while ,大家注意看nn的值,外循环k+=2 ,当k>=4时 nn=2,,而C语言中却有这么一句
delta=c[nn-1]*c[nn-1]-(c[nn-1]-b[nn-1])*c[nn-3];
我翻译过来哦后,一直抛 java.lang.ArrayIndexOutOfBoundsException,很明显是 c[nn-3] 中的nn-3为负数,而在C语言中却不会报错,调试后,才发现,当C语言中,数组下标为负数时,其值为0 。
这才算改过来啦。
b[nn]=nn>=2?a[nn]-p*b[nn-1]-q*b[nn-2]:a[nn]-p*b[nn-1] ; delta=nn>=3?c[nn-1]*c[nn-1]-(c[nn-1]-b[nn-1])*c[nn-3]:c[nn-1]*c[nn-1] ; deltap=nn>=3?(b[nn-1]*c[nn-2]-b[nn]*c[nn-3])/delta:(b[nn-1]*c[nn-2])/delta;
之后,和原算法执行效果是一样的。 切记、java中数组下标不可为负,而C语言中,可以,并且其值为0 !!!