计算方法实验报告班级: 学号: 姓名: 成绩:1 舍入误差及稳定性一、实验目的(1)通过上机编程,复习巩固以前所学程序设计语言及上机操作指令;(2)通过上机计算,了解舍入误差所引起的数值不稳定性二、实验内容1、用两种不同的顺序计算1000021n n -=∑,分析其误差的变化 2、已知连分数()101223//(.../)n n a f b b a b a a b =++++,利用下面的算法计算f : 11,i n n i i i a d b d b d ++==+ (1,2,...,0)i n n =-- 0f d = 写一程序,读入011,,,...,,,...,,n n n b b b a a 计算并打印f3、给出一个有效的算法和一个无效的算法计算积分1041nn x y dx x =+⎰ (0,1,...,10)n = 4、设2211N N j S j ==-∑,已知其精确值为1311221N N ⎛⎫-- ⎪+⎝⎭(1)编制按从大到小的顺序计算N S 的程序(2)编制按从小到大的顺序计算N S 的程序(3)按两种顺序分别计算10001000030000,,,S S S 并指出有效位数三、实验步骤、程序设计、实验结果及分析1、用两种不同的顺序计算1000021n n -=∑,分析其误差的变化 (1)实验步骤:分别从1~10000和从10000~1两种顺序进行计算,应包含的头文件有stdio.h 和math.h(2)程序设计:a.顺序计算#include<stdio.h>#include<math.h>void main(){double sum=0;int n=1;while(1){sum=sum+(1/pow(n,2));if(n%1000==0)printf("sun[%d]=%-30f",n,sum);if(n>=10000)break;n++;}printf("sum[%d]=%f\n",n,sum);}b.逆序计算#include<stdio.h>#include<math.h>void main(){double sum=0;int n=10000;while(1){sum=sum+(1/pow(n,2));if(n%1000==0)printf("sum[%d]=%-30f",n,sum);if(n<=1)break;n--;}printf("sum[%d]=%f\n",n,sum);}(3)实验结果及分析:程序运行结果:a.顺序计算b.逆序计算结果分析:两种不同顺序计算结果是一样的,顺序计算误差从一开始就很小,而逆序计算误差最开始十分大,后来结果正确。
2、已知连分数()101223//(.../)n n a f b b a b a a b =++++,计算f : (1)实验步骤:利用 11,i n n i i i a d b d b d ++==+ (1,2,...,0)i n n =--,0f d =,计算f (2)程序设计#include<stdio.h>#include<math.h>void main(){int i=0,n;float a[1024],b[1024],d[1024];printf("please input n,n=");scanf("%d",&n);printf("\nplease input a[1] to a[n]:\n");for(i=1;i<=n;i++){printf("a[%d]=",i);scanf("%f",&a[i]);}printf("\nplease input b[0] to b[n]:\n");for(i=0;i<=n;i++){printf("b[%d]=",i);scanf("%f",&b[i]);}d[n]=b[n];for(i=n-1;i>=0;i--)d[i]=b[i]+a[i+1]/d[i+1];printf("\nf=%f\n",d[0]);}(3)实验结果程序运行结果:3、给出一个有效的算法和一个无效的算法计算积分1041nn x y dx x =+⎰ (0,1,...,10)n = (1)实验步骤利用C 语言编写程序,分别使用数值稳定的和数值不稳定的计算公式所建立的递推公式进行计算。
(2)程序设计#include<stdio.h>#include<math.h>main(){double y_0=(1/4.0)*log(5),y_1;double y_2=(1.0/55.0+1.0/11.0)/2,y_3;int n=1,m=10;printf("有效算法输出结果:\n");printf("y[0]=%-20f",y_0);while(1){y_1=1.0/(4*n)+y_0/(-4.0);printf("y[%d]=%-20f",n,y_1);if(n>=10) break;y_0=y_1;n++;if(n%3==0) printf("\n");}printf("\n 无效算法的输出结果:\n");printf("y[10]=%-20f",y_2);while(1){y_3=1.0/n-4.0*y_2;printf("y[%d]=%-20f",m-1,y_3);if(m<=1) break;y_2=y_3;m--;if(m%2==0) printf("\n");}}(3)实验结果及分析程序运行结果:结果分析:无效算法数值不稳定,误差造成的影响特别大4、设2211N N j S j ==-∑,已知其精确值为1311221N N ⎛⎫-- ⎪+⎝⎭(1)实验步骤先编程按从大到小的顺序计算N S 的程序,再编程按从小到大的顺序计算N S 的程序,然后按两种顺序分别计算10001000030000,,S S S 。
(2)程序设计#include<stdio.h>main(){int N;double SN[30000];SN[30000]=(3.0/2.0-1.0/30000.0-1/30001.0)/2.0;for(N=30000;N>=2;N--)SN[N-1]=SN[N]-1.0/(N*N-1);printf("从大到小顺序计算:\nSN[1000]=%f\nSN[10000]=%f\nSN[30000]=%f\n",SN[1000],SN[10000],SN[30000]);SN[2]=(3.0/2-1.0/2.0-1/3.0)/2.0;for(N=3;N<=30000;N++)SN[N]=SN[N-1]+1.0/(N*N-1);printf("从小到大顺序计算:\nSN[1000]=%f\nSN[10000]=%f\nSN[30000]=%f\n",SN[1000],SN[10000],SN[30000]); }(3)实验结果及分析程序运行结果:结果分析:不同顺序计算所得结果是一样的。
四、总结通过这次上机,学习了解了舍入误差在不同算法时对结果的影响不同,稳定的算法才能获得正确的结果。
2 方程求根一、实验目的(1)通过对二分法与牛顿迭代法做编程练习和上机运算,进一步体会二分法和牛顿法的不同。
(2)编写割线迭代法的程序,求非线性方程的解,并与牛顿迭代法作比较。
二、实验内容1、用牛顿法求下列方程的根(1)20xx e -=(2)10x xe -=(3)lg 20x x +-=2、编写割线法程序求解第一问的方程 三、实验步骤、程序设计、实验结果及分析1、牛顿法(1)实验步骤通过定义牛顿法求方程的子函数,用main函数调用子函数求根(2)程序设计#include <stdio.h>#include <math.h>typedef float (*p)(float );float ff1(float x){return x*x-exp(x);}float ff2(float x){return x*exp(x)-1;}float ff3(float x){return log(x)+x-2;}float answer(float(*p)(float)){int k=2;float m=1,n=-1,x2,a,b,c;if (p==ff3)n=2;printf("x[0] = %.4f, x[1] = %.4f, ",m,n);while (1){if (fabs(m-n)<1e-4) break;a=p(n)*(n-m);b=p(n)-p(m);c=a/b;x2=n-c;m = n;n = x2;printf("x[%d] = %.4f, ",k,x2);k++;if (k%3==0) printf("\n");}if (k%3!=0) printf("\n");printf("iteration times: %d, roots: %.4f\n ",k-2,n);return 0;}main(){printf("x*x-exp(x),\n");answer(ff1);printf("x*exp(x)-1,\n");answer(ff2);printf("lg(x)+x-2,\n");answer(ff3);return 0;}(3)实验结果及分析2、割线法(1)程序设计#include<stdio.h>#include<math.h>float gexian(float,float);float f(float);main(){int i,j;float x1=2.2;float x2=2,x3;scanf("%d",&i);if(i==1) printf("%f",x1); else if(i==2) printf("%f",x2); else{for(j=3;j<=i;j++){x3=gexian(x1,x2);x1=x2;x2=x3;}printf("%f",gexian(x1,x2)) ;}}float f(float x){return (x*x-exp(x));}float gexian(float x1,float x2){return (x2-(f(x2)/(f(x2)-f(x1)))*(x2-x1));}(3)实验结果及分析四、总结了解和学习了二分法和牛顿迭代法的思想以及程序设计的方法,比较了迭代法和牛顿法的特点:牛顿法收敛速度较快,但对初值选取要求较高;割线法计算量少。