以文本方式查看主题

-  中华农历论坛  (http://bbs.nongli.net/index.asp)
--  历法知识  (http://bbs.nongli.net/list.asp?boardid=2)
----  [求助]请教JavaScript高手,这一行代码怎么理解  (http://bbs.nongli.net/dispbbs.asp?boardid=2&id=47094)

--  作者:秦汉昌
--  发布时间:2011/6/10 22:26:00
--  [求助]请教JavaScript高手,这一行代码怎么理解

//最简单PI计算javascript程序,2006.12 许剑伟 莆田十中

function GJ2_pi(){//,本程序所得最后5位可能有错
 var N=GJ2_N.value-0+1, a=new Array(); //N为计算的位数
 var i=Math.round(3.4*N),b=2*i+1, j,f;
 for(j=0;j<N;j++) a[j]=0;    //PI结果数组初始化
 for(;i>0; i--,b-=2,a[0]+=2) //每计算3.4次得到1位十进制精度
  for(j=0,f=0;j<N;j++){      //多精度a与单精度b相除算法(小学除法),分子i,分母2*i+1
    f = a[j]*i+f*10;
    a[j] = Math.floor(f/b);
    f %= b;
  }
 for(i=N-1;i>0;i--) a[i-1] += Math.floor(a[i]/10), a[i] %= 10; //进位处理
 a[0]=\'<br>\'; for(i=1;i<N;i++) {if(i%10==0) a[i]+=\' \'; if(i%100==0) a[i]+=\'<br>\';} //换行处理
 GJ2_out.innerHTML=
   \'本算法为低速算法,计算位数不宜过大,否则计算时间太长。<br>\'
  +\'以下计算圆周率,计算公式:PI/2=1+1/3+1*2/(1*3*5)+1*2*3/(1*3*5*7)+...<br>\'
  +\'通过提取公因子得连分式形式:PI=2+1/3(2+2/5(2+3/7(2+...,这样只需迭代计算a=2+a*n/(2n+1),n=N,…3,,2,1即可得到a=PI<br>\'
  +\'最后5位可能有错:<font color=red>PI=3.\' + a.join(\'\') + \'</font>\';

}

 

 

 

 for(;i>0; i--,b-=2,a[0]+=2) //每计算3.4次得到1位十进制精度

 

像这样的语句,没有循环体,也没有分号与下面的语句分隔,我们应该怎么来理解它所实现的功能呢,这个循环语句与下一个循环语言是不是嵌套 关系 呢?,我用汉语代码改写成嵌套关系,发现不正常。


--  作者:浪-淘-沙
--  发布时间:2011/6/11 8:18:00
--  
以下是引用秦汉昌在2011-6-10 22:26:00的发言:

 for(;i>0; i--,b-=2,a[0]+=2) //每计算3.4次得到1位十进制精度
  for(j=0,f=0;j<N;j++){      //多精度a与单精度b相除算法(小学除法),分子i,分母2*i+1
    f = a[j]*i+f*10;
    a[j] = Math.floor(f/b);
    f %= b;
  }
 
 

像这样的语句,没有循环体,也没有分号与下面的语句分隔,我们应该怎么来理解它所实现的功能呢,这个循环语句与下一个循环语言是不是嵌套 关系 呢?,我用汉语代码改写成嵌套关系,发现不正常。

这二个for语句就是嵌套循环啊。

 

还有,i--是表示,先把i值进入循环一圈后,i的值再减1。

与--i的计算顺序正好相反。

 

你再试着修改一下程序吧。


--  作者:秦汉昌
--  发布时间:2011/6/12 14:05:00
--  

可这个程序,在坟算中,确实有问题:

假如:N=N+1=101

那么:i=343,b=687

第一次循环,由于a[0]的初值为0,a[0]*i+f*10=0,所以,本次循环无效

第二次循环,i=342,b=385,a[0]=2;

                 f=a[0]*i+f*10=2*342+0*10=684

                 f<b,即684<685,这样,f/b的值会永远为0,所以,an的值无法得到改变.....因此也无效

      在下一次循环中,由于f被 重新赋0值,所以,与第二次循环的运行结果一样,以此类推,这个循环嵌套无意义。

 

 

呵呵,请高手指点,我这样分析,正确否?


--  作者:浪-淘-沙
--  发布时间:2011/6/12 15:05:00
--  

我不懂“中文编程”,所以很难帮你分析。

 

你知道for循环的括号里有两个“分号”吧?

第一个分号之前的,属于初始条件,可以省略。

第一个分号与第二个分号之间的,属于循环判断条件。

第二个分号之后的,一般用来给循环数增加(或减小)。

for(;i>0; i--,b-=2,a[0]+=2)

其中i>0判断循环是否继续。

只要i>0,就会进入下一层的for循环啊。

为何你说循环无效?

 

那几句JAVASCRIPT,我觉得没有什么特别难懂的地方。

只要学过“C编程”的朋友,都能很容易理解的啊。


--  作者:浪-淘-沙
--  发布时间:2011/6/12 15:07:00
--  

第一次循环,由于a[0]的初值为0,a[0]*i+f*10=0,所以,本次循环无效

根本不是判断这个数啊。

是判断i>0是否成立。

 

第一个分号之前的内容被省略了。你以为判断条件就是另一个了吧?


--  作者:浪-淘-沙
--  发布时间:2011/6/12 15:13:00
--  

如果把for循环写成

i=0;a=0;

for( ;i > 10  ; )

{a = a +1;

i = i +1; //循环变量,本来它是写在第二个分号之后的。但若把它到程序中,照样没问题的。

}

 

那么就与while循环没什么区别了(它的括号里,只有一个条件,不用分号隔开)。

i=0;a=0;

while(i > 10 )

{a = a +1;

i = i +1;

}

 

上面二段代码是等价的。

如果你能明白,那么你就应当明白你自己的“中文编程”里的代码有问题了。


--  作者:客人
--  发布时间:2011/6/13 16:47:00
--  
我所谓的无效,不是指编程意义上的不成立或者不可以,从程序运行的角度,是不会有异常的
我所讲的无效,是从文天计算的角度考虑的,无一个数据通过一次循环运算后,对结果没有影响,我认为无效操作

当然,在N 次循环中,有一些无效操作是必然的,但是,如果整个循环都不能对结果产生影响,那么,是数据计算的绝对无效操作了
--  作者:秦汉昌
--  发布时间:2011/6/13 16:59:00
--  
以下是引用浪-淘-沙在2011-6-12 15:07:00的发言:

根本不是判断这个数啊。

是判断i>0是否成立。

 

第一个分号之前的内容被省略了。你以为判断条件就是另一个了吧?

我所说的无效,是从文天计算上考虑的,并不是讨论循环条件,而是讨论程序算法,我认为 循环嵌套中的代码运算对计算结果没有产生影响,所以,说它是无效操作,并非指程序不能正常运行

 

 

  经测试,JavaScript代码无误,是我对算法没有理解明白

 

  呵呵,浪版,可以这个程序的算法给我讲解一下吗

 


--  作者:浪-淘-沙
--  发布时间:2011/6/13 17:17:00
--  
以下是引用秦汉昌在2011-6-13 16:59:00的发言:

我所说的无效,是从文天计算上考虑的,并不是讨论循环条件,而是讨论程序算法,我认为 循环嵌套中的代码运算对计算结果没有产生影响,所以,说它是无效操作,并非指程序不能正常运行

 

  可能 是我对算法没有理解清楚  ,我还是认为。循环嵌套中内部循环中的每一位的商永远都会是0,因为被除数永远小于除数,因为外循环对a0的累加 被内循环的0商置0,如此循环下去,永远无法除出非零商来。

 

  呵呵,浪版,可以这个程序的算法给我讲解一下吗

 

首先你要相信,原作者那个程序是可以正常运行的,即可以计算出“圆周率”的。

那么你为何认为循环无效呢?

如果真的如你所说循环无效,那原程序又如何计算出圆周率。

 

然后,下面这二个语句,你是否真的看明白了?

a[j] = Math.floor(f/b);
    f %= b;//这是求余数运算啊。比如f=20,b=15,则f %= b结果是f=5.


--  作者:浪-淘-沙
--  发布时间:2011/6/13 17:20:00
--  

      在下一次循环中,由于f被 重新赋0值,所以,与第二次循环的运行结果一样,以此类推,这个循环嵌套无意义。

 

 

呵呵,请高手指点,我这样分析,正确否?

我觉得你还是没明白for循环的原理啊。

什么叫下一次循环中,f被重赋值啊?

 

for循环中,第一个分号“;”之前的语句,在循环中只执行一次啊。难道你理解成它每次都要执行的?