数值分析上机作业最强版

  • 格式:docx
  • 大小:338.68 KB
  • 文档页数:25

下载文档原格式

  / 25
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

数值分析上机作业

**:**

学号:******

专业:道路与铁道工程

院系:交通学院

****:***

日期:2015年1月

习题一

1 题目

17.(上机题)舍入误差与有效数 设2

21

1N

N j S j ==-∑

,其精确值为1311221N N ⎛⎫

-- ⎪+⎝⎭

。 (1)编制按从大到小的顺序22

2

11

1

2131

1

N S N =+++

---,计算N S 的通用程序; (2)编制按从小到大的顺序22211

11(1)1

21

N S N N =

+++

----,计算N S 的通用程序; (3)按两种顺序分别计算210S ,410S ,610S ,并指出有效位数。(编制程序时用单精度);

(4)通过本上机题你明白了什么?

2 通用程序代码

2.1 按从小到大的顺序计算N S

void AscendSum(unsigned long int N)// 计算从大到小的总和 {

for (unsigned long int j=2;j<=N;j++) ascendSum+=(float )1.0/(j*j-1);

cout<<"Sum From 1 to N (Ascend) is: "<

} 2.2 按从大到小的顺序计算N S

void DescendSum(unsigned long int N)//计算从小到大的总和 {

for (unsigned long int j=N;j>=2;j--) descendSum+=(float )1.0/(j*j-1);

cout<<"Sum From N to 1 (Descend) is: "<

}

3计算结果展示

图1 N=100时的计算结果

图2 N=10000时的计算结果

图3 N=1000000时的计算结果

表1-1 计算结果汇总

N S

精确值

按从小到大

按从大到小

N S 值

有效位数 N S 值

有效位数

210S 0.7400494814 0.7400494814 10 0.740049541 6 410S 0.7498999834 0.7498521209 4 0.7498999834 10 610S

0.7499989867

0.751856029

2

0.7529925108

2

4 计算结果分析

(1)如果采用单精度数据结构进行计算,则相较于双精度的数据结果,由于数据存储字长的限制导致计算机存在较大的舍入误差,因此本程序采用的是双精度数据存储方式。

(2)由计算结果可知,正序计算和逆序计算的精度是不稳定的。由计算结果可以发现,当N=100时,正序计算(1-N )的精度较高;当N=10000时,逆序计算(N-1)的精度较高;当N=1000000时,正序计算和逆序计算的精度一样。

当然,和其他同学做出来的结果对比,结论并不一致。我个人分析这是因为电脑的硬件、软件(位数)不同等原因导致的。但总体而言,在N 较小时,正序计算精度高于逆序计算的精度。当N 较大时,正序和逆序计算的精度接近。

(3)由于计算机的实际计算过程是一种舍入机制,故对于我们计算所采用的加法交换律是不成立的。计算机中若干数相加时,先要进行对阶操作,即将两数的阶数统一为绝对值较大的数的阶数。这样一来将导致绝对值较小的数的有效数字可能会大量损失,增大舍入误差,即所谓的“大数吃小数”现象。为了避免这种现象的出现,在进行加减法的时候应该先将绝对值较小的数相加,再与绝对值较大的数相加这样按阶逐步递增的相加。

5 完整代码

#include #include #include using namespace std;

float accurateSum=0,ascendSum=0,descendSum=0;

void Delimiter()//输出一系列星号以间隔 {

for (int i=1;i<=50;i++) cout<<"*";

cout<

}

void Error(float Sum)//计算绝对误差

{

float error;

error=fabs(Sum-accurateSum);

int flag;

for(flag=0;flag<10;flag++)

{

error=error*10;

if (error>0.5)

break;

}

cout<<"There are "<

}

void AccurateSum(unsigned long int N)//计算精确值

{

accurateSum=0.5*(1.5-(float)1/N-(float)1/(N+1));

cout<<"Accurate sum is: "<

Delimiter();

}

void AscendSum(unsigned long int N)//计算从大到小的总和

{

for(unsigned long int j=2;j<=N;j++)

ascendSum+=(float)1.0/(j*j-1);

cout<<"Sum From 1 to N (Ascend) is: "<

Error(ascendSum);

Delimiter();

}

void DescendSum(unsigned long int N)//计算从小到大的总和

{

for(unsigned long int j=N;j>=2;j--)

descendSum+=(float)1.0/(j*j-1);

cout<<"Sum From N to 1 (Descend) is: "<

Error(descendSum);

Delimiter();

}

void main()//主程序

{