- 注册时间
- 2010-10-22
- 最后登录
- 1970-1-1
- 威望
- 星
- 金币
- 枚
- 贡献
- 分
- 经验
- 点
- 鲜花
- 朵
- 魅力
- 点
- 上传
- 次
- 下载
- 次
- 积分
- 2292
- 在线时间
- 小时
|
发表于 2010-11-30 10:02:23
|
显示全部楼层
考虑到一个现象,发现做减法有个好处,我们知道欧拉公式,lim(1+1/2+1/3+……+1/n) =In(n)+ C
从n=8开始,可以满足本题的精度要求,所以有如下估计式
1/10000000+1/10000001+...+1/99999999=ln(99999999/9999999) 这个常数用系统自带的计算器就可以算出来
同理n=9以可以算出。
这样一来,时间缩短了1/3。以前上面的程序在我机子上要运行9.16s ,现在只需要2.59s
(小数点前6位均准确,所以下面的结果只输出了前6位(这无效率影响,上面的9.16s也是只输出前6位的时间))- #include <stdio.h>
- #include <time.h>
-
- void disp(double s0,double s9,int n)
- {
- printf( "s0[%d] = %.6f\ns9[%d] = %.6f\ns0/s9 = %.6f\n\n\n", n,s0,n,s9,s0/s9);
- }
-
- double calcS(int n)//n=1,2,3,...,7
- {
- int e[10]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};
- int k;
- double s=0.0;
- for(k=e[n-1];k<e[n];k++)
- s+=1.0/k;
- return s;
- }
-
- //------------------------------
- double search_1()
- {
- double s9,s0=0.0;
- int k;
- for (k=1;k<=8;k++)
- s0+=1.0/k;
- return s0;
-
- }
-
- double search_2()
- {
- double s9,s0=0.0;
- int a,b,k=10;
- for (b=1;b<=8;b++,k+=1)
- for (a=0;a<=8;a++,k++)
- s0+=1.0/k;
- return s0;
-
- }
-
- double search_3()
- {
- double s9,s0=0.0;
- int a,b,c,k=100;
- for (c=1;c<=8;c++,k+=10)
- for (b=0;b<=8;b++,k+=1)
- for (a=0;a<=8;a++,k++)
- s0+=1.0/k;
- return s0;
-
- }
-
- double search_4()
- {
- double s9,s0=0.0;
- int a,b,c,d,k=1000;
- for (d=1;d<=8;d++,k+=100)
- for (c=0;c<=8;c++,k+=10)
- for (b=0;b<=8;b++,k+=1)
- for (a=0;a<=8;a++,k++)
- s0+=1.0/k;
- return s0;
-
- }
-
- double search_5()
- {
- double s9,s0=0.0;
- int a,b,c,d,e,k=10000;
- for (e=1;e<=8;e++,k+=1000)
- for (d=0;d<=8;d++,k+=100)
- for (c=0;c<=8;c++,k+=10)
- for (b=0;b<=8;b++,k+=1)
- for (a=0;a<=8;a++,k++)
- s0+=1.0/k;
- return s0;
-
- }
-
- double search_6()
- {
- double s9,s0=0.0;
- int a,b,c,d,e,f,k=100000;
- for (f=1;f<=8;f++,k+=10000)
- for (e=0;e<=8;e++,k+=1000)
- for (d=0;d<=8;d++,k+=100)
- for (c=0;c<=8;c++,k+=10)
- for (b=0;b<=8;b++,k+=1)
- for (a=0;a<=8;a++,k++)
- s0+=1.0/k;
- return s0;
-
- }
-
- double search_7()
- {
- double s9,s0=0.0;
- int a,b,c,d,e,f,g,k=1000000;
- for (g=1;g<=8;g++,k+=100000)
- for (f=0;f<=8;f++,k+=10000)
- for (e=0;e<=8;e++,k+=1000)
- for (d=0;d<=8;d++,k+=100)
- for (c=0;c<=8;c++,k+=10)
- for (b=0;b<=8;b++,k+=1)
- for (a=0;a<=8;a++,k++)
- s0+=1.0/k;
- return s0;
-
- }
-
- double search_8()
- {
- double s9,s0=0.0;
- int a,b,c,d,e,f,g,h,k=10000000;
- for (h=1;h<=8;h++,k+=1000000)
- for (g=0;g<=8;g++,k+=100000)
- for (f=0;f<=8;f++,k+=10000)
- for (e=0;e<=8;e++,k+=1000)
- for (d=0;d<=8;d++,k+=100)
- for (c=0;c<=8;c++,k+=10)
- for (b=0;b<=8;b++,k+=1)
- for (a=0;a<=8;a++,k++)
- s0+=1.0/k;
- return s0;
-
- }
-
- double search_9()
- {
- double s9,s0=0.0;
- int a,b,c,d,e,f,g,h,i,k=100000000;
- for (i=1;i<=8;i++,k+=10000000)
- for (h=0;h<=8;h++,k+=1000000)
- for (g=0;g<=8;g++,k+=100000)
- for (f=0;f<=8;f++,k+=10000)
- for (e=0;e<=8;e++,k+=1000)
- for (d=0;d<=8;d++,k+=100)
- for (c=0;c<=8;c++,k+=10)
- for (b=0;b<=8;b++,k+=1)
- for (a=0;a<=8;a++,k++)
- s0+=1.0/k;
- return s0;
-
- }
- int main()
- {
- double s0[10]={0};
- double s9[10]={0};
- //由欧拉公式lim(1+1/2+...+1/n)=lnn+C (n->无穷,c为常数)
- //从第n=8开始,n值以达到其极限的精度要求
- //完全可以用估计式ln( n/m )=1/n +1/(n-1)+...+1/(m+1)
- //这样明显减少计算时间
- double s_8=2.3025851829940506340183244547094;
- double s_9=2.3025851019940457335179917876844;
-
- double t0=clock();
-
- s0[1]=search_1();
- s0[2]=search_2();
- s0[3]=search_3();
- s0[4]=search_4();
- s0[5]=search_5();
- s0[6]=search_6();
- s0[7]=search_7();
- s0[8]=search_8();
- s0[9]=search_9();
-
-
- s9[1]=calcS(1)-s0[1];
- disp(s0[1],s9[1],1);
- s9[2]=calcS(2)-s0[2];
- disp(s0[2],s9[2],2);
- s9[3]=calcS(3)-s0[3];
- disp(s0[3],s9[3],3);
- s9[4]=calcS(4)-s0[4];
- disp(s0[4],s9[4],4);
- s9[5]=calcS(5)-s0[5];
- disp(s0[5],s9[5],5);
- s9[6]=calcS(6)-s0[6];
- disp(s0[6],s9[6],6);
- s9[7]=calcS(7)-s0[7];
- disp(s0[7],s9[7],7);
- //==================
- s9[8]=s_8-s0[8];
- disp(s0[8],s9[8],8);
- s9[9]=s_9-s0[9];
- disp(s0[9],s9[9],9);
-
- printf("Elapsed time: %f s\n",(clock()-t0)/CLOCKS_PER_SEC);
- system("Pause");
- return 0;
- }
复制代码 结果:
s0[1] = 2.717857
s9[1] = 0.111111
s0/s9 = 24.460714
s0[2] = 2.053992
s9[2] = 0.294418
s0/s9 = 6.976456
s0[3] = 1.817871
s9[3] = 0.489222
s0/s9 = 3.715842
s0[4] = 1.633364
s9[4] = 0.669671
s0/s9 = 2.439055
s0[5] = 1.469783
s9[5] = 0.832847
s0/s9 = 1.764771
s0[6] = 1.322783
s9[6] = 0.979807
s0/s9 = 1.350045
s0[7] = 1.190503
s9[7] = 1.112083
s0/s9 = 1.070516
s0[8] = 1.071452
s9[8] = 1.231133
s0/s9 = 0.870298
s0[9] = 0.964307
s9[9] = 1.338278
s0/s9 = 0.720558
Elapsed time: 2.599000 s
请按任意键继续. . . |
|