Fortran95课程设计.docx
《Fortran95课程设计.docx》由会员分享,可在线阅读,更多相关《Fortran95课程设计.docx(24页珍藏版)》请在冰豆网上搜索。
Fortran95课程设计
Fortran95
课程设计
一,任务书...............................................................................1
二,员工档案(工资和个人所得税)..................................6
三,求解方程.........................................................................11
1,求解一元方程的根
................................11
1-1,二分法求解
1-2,弦截法求解
1-3,Newton迭代法求解.....................................................13
2,求方程的积分
.......................................15
2-1,矩形法积分
2-2,梯形法积分
2-3,辛普生法积分
3,Gauss-Jordan法求联立方程组....................................18
四,课程总结............................................................................22
2012级FORTRAN95程序设计语言课程设计任务书
一、实践目的
通过本课程设计、加深学生对所学程序设计语言的理解,培养其程序设计能力以及综合解决实际问题的能力。
通过自己分析问题、分解问题、查找算法、编写、调试程序的过程,掌握FORTRAN95程序设计与调试方法,提高应用所学知识借助计算机程序解决具体问题的能力。
二、设计任务
1、综合应用所学FORTRAN95知识点解决具体问题。
某小型公司有员工25人,员工信息包括员工编号,姓名,性别,工龄,工资(为方便,视其为三险一金减除后的金额),现在需要对这25名员工按照其工资进行个人信息的排序,计算每个人的个人所得税并添加到个人信息中。
请按以下要求进行设计
⑴利用记事本创建员工基本信息文件。
⑵设计包含以上信息内容的派生类和结构体数组。
⑶以结构体数组为虚参编写排序子程序,可使用简单交换法、选择法和冒泡法中的任何一种。
⑷以普通变量为虚参,编写函数子程序计算个人所得税子程序。
⑸编写主程序完成以上工作,并将包含所得税信息的员工信息输出到另一个文本文件。
2、科学计算问题(三选二)
ⅰ一元方程的根
分别采用二分法、弦截法和牛顿迭代法求解一元方程的根。
要求如下:
⑴用子程序编写求解一元方程的算法
⑵一元方程自选,要求人人不同
⑶在主程序中要调用三种方法计算同一个一元方程的根
ⅱ某函数在某指定区间上的定积分计算
分别采用矩形法、梯形法和辛普森法求解某个函数在给定区间上的定积分。
要求如下:
⑴用子程序编写求解定积分的算法
⑵函数自选,积分区间自定,要求人人不同
⑶在主程序中要调用三种方法计算同一个定积分。
ⅲ线性方程组
采用GAUSS-JORDAN法求线性方程组的根,要求如下:
⑴用子程序编写上、下三角矩阵
⑵方程组自选,要求人人不同。
三、设计报告
1、任务内容:
描述所选题目的内容
2、设计思想描述:
绘制各个问题算法的流程图
3、源程序
4、编程中遇到的问题、困难及其解决办法
5、总结
6、参考文献
四、参考文献
1、本学期教材
2、网上个人所得税资料
3、计算方法方面的书籍
五、考核方式及评分办法
1、程序调试结果占总课程设计成绩的60%
2、课程设计报告书占总课程设计成绩的30%
3、课程设计活动活跃度(提问)占总课程设计成绩的10%
课程设计报告书的有关规定
1、报告书需提交电子档和纸质档各一份。
2、报告书封面应写明本课程设计的名称和学院、专业、姓名、学号和指导教师姓名。
3、正文部分标题为宋体二号字,小标题宋体四号加粗。
正文宋体小四号,行距1.5。
源程序可采用分栏排版减少页面。
4、报告书中必须要有任务说明、设计思想阐述、源程序、程序运行结果截图、总结和参考文献部分
5、若发现抄袭的,成绩直接判定不及格。
1,员工档案
某小型公司有员工25人,员工信息包括员工编号,姓名,性别,工龄,工资(为方便,视其为三险一金减除后的金额),现在需要对这25名员工按照其工资进行个人信息的排序,计算每个人的个人所得税并添加到个人信息中。
思想:
首先定义一个派生类型worker_information,其员工信息包括姓名name,性别sex,工龄age,工资salary,个人所得税tax再根据派生类型声明一个结构体数组tax(n)其元素个数为员工人数。
通过一个主程序,调用两个子程序,完成个人所得税的计算及其排序。
编写程序如下:
programworker_information
parameter(n=25)
typeworker_inform
character*6name
character*2sex
integerage
integersalary
realtax
endtype
type(worker_inform)work(n)
open(1,file='information1.txt')
doi=1,n
read(1,10)work(i)%name,work(i)%sex,work(i)%age,work(i)%salary
enddo
10format(a6,3x,a2,6x,i2,9x,i8)
close
(1)
doi=1,n
work(i)%tax=tax(work(i)%salary)
enddo
open(2,file='information2.txt')
doi=1,n
write(2,20)work(i)
enddo
20format(a6,3x,a2,6x,i2,9x,i8,f10.2)
open(3,file='information3.txt')
callfun(work,n)
doi=1,n
write(3,100)work(i)
enddo
100format(a6,3x,a2,6x,i2,9x,i8,f10.2)
contains
functiontax(x)
realtax
integerx
if(x<=1500)then
tax=x*0.03
elseif(x>1500.and.x<=4500)then
tax=1500*0.03+(x-1500)*0.10
elseif(x>4500.and.x<=9000)then
tax=1500*0.03+3000*0.10+(x-4500)*0.20
elseif(x>9000.and.x<=35000)then
tax=1500*0.03+3000*0.10+4500*0.20+(x-9000)*0.25
elseif(x>35000.and.x<=55000)then
tax=1500*0.03+3000*0.10+4500*0.20+26000*0.25+(x-35000)*0.30
elseif(x>5500.and.x<=80000)then
tax=1500*0.03+3000*0.10+4500*0.20+26000*0.25+20000*0.30+(x-55000)*0.40
else
tax=x*0.40
endif
endfunction
subroutinefun(a,n)
type(worker_inform)a(n),t
doi=1,n-1
doj=i+1,n
if(a(i)%salaryt=a(i)
a(i)=a(j)
a(j)=t
endif
enddo
enddo
endsubroutine
end
原表:
●
●
●
2,求函数f(x)=
的解
2-1二分法与弦切法:
思想:
(1)先任取两个值x1,x2,使得f(x1)*f(x2)<0,也就是f(x1)和f(x2)必须异号。
(2)令x=(x1+x2)/2,如果f(x)=0,就找到了这个解,计算完成。
由于f(x)是一个实型数据,所以在判断f(x)是否等于0时,是通过判断
是否小于一个很小的数ε,如果是就认为f(x)为0
(3)如果f(x)不为0,判断如果f(x1)和F(x)异号,则说明解在
区间,就以x1,x为新的取值来重复步骤
(2),这时用x作为新的x2,舍掉原
区间;如果F(x2)和f(x)异号,则以x,x2为新的取值来步骤重复
(2),这是用x作为新的x1,舍掉原
区间。
这样做实际上是将求解的范围减小了一半,然后用同样的方法再进一步缩小范围,直到
小于ε为止。
programsubject2_1
realx1,x2,x
realcourse1,course2,fun
do
print*,"输入x1,x2的值:
"
read*,x1,x2
if(fun(x1)*fun(x2)<0.0)exit
print*,"不正确的输入!
"
enddo
x=course1(x1,x2)
print*,"二分法求解得:
"!
二分法
print10,'x=',x
x=course2(x1,x2)
print*,"弦切法求解得:
"!
弦切法
print10,'x=',x
10format(a,f10.6)
end
realfunctioncourse1(x1,x2)!
二分法求解
realx1,x2,f1,f2,fx
x=(x1+x2)/2.0
fx=fun(x)
dowhile(abs(fx)>1e-6)
f1=fun(x1)
if(f1*fx<0)then
x2=x
else
x1=x
endif
x=(x1+x2)/2.0
fx=fun(x)
enddo
course1=x
end
realfunctioncourse2(x1,x2)!
弦切法求解
realx1,x2,f1,f2,fx
x=x2-(x2-x1)/(fun(x2)-fun(x1))*fun(x2)
fx=fun(x)
dowhile(abs(fx)>1e-6)
f1=fun(x1)
if(f1*fx<0)then
x2=x
else
x1=x
endif
x=x2-(x2-x1)/(fun(x2)-fun(x1))*fun(x2)
fx=fun(x)
enddo
course2=x
end
functionfun(x)
realx
fun=x**3-4*x**2+9*x+4
end
打印结果如下:
Newton迭代法
思想:
用牛顿迭代法求解一元方程的根,基本思路为:
(1)先任取一个x1。
(2)做通过点(x1,f(x1))做切线,即以f'(x1)为斜率作直线,这条直线与x轴的交点为x2,用以下公式求出x2由于f'(x1)=
;x2=x1-
.判断
<ε是否成立,如果是就找到了解,计算完成,(3)否则,重复步骤
(2)以f'(x1)为斜率过点(x2,f(x2)),求出与x轴都的交点x3,……直到
<ε,认为xn就是所求得的解。
programsubject2_3
realx
integerm
print*,'输入初值以及循环次数'
read*,x,m
callnewton(x,m)
end
subroutinenewton(x,m)
implicitnone
realx,x1
realfun,dfun
integeri,m
i=1
x1=x-fun(x)/dfun(x)
dowhile(abs(x-x1)>1e-6.and.i<=m)
print10,i,x1
x=x1
i=i+1
x1=x-fun(x)/dfun(x)
enddo
if(i<=m)then
print20,'x=',x1
else
print30,'经过',m,'次迭代后仍未收敛'
endif
10format('i=',i4,6x,'x=',f15.7)
20format(a,f15.7)
30format(a,i4,a)
end
realfunctionfun(x)
realx
fun=x**3-4*x**2+9*x+4
end
打印结果:
2-2,求函数函数积分
矩形法:
s=s+fun(x)*h
梯形法:
s=s+(fun(x+(i-1)*h)+fun(x+i*h))*h/2.0
辛普生法:
sinpson=(fun(a)+fun(b)+4.0*f4+2.0*f2)*h/3.0
思想:
求一个函数f(x)在
上的定积分
,其几何意义是求f(x)曲线
和直线x=a,y=0,x=b所围成的曲边梯形的面积。
为了近似求出这一面积,可将
分成若干个小区间,每个区间的宽度为(b-a)/n,n为区间个数,近似求出每个小的区边梯形的面积,然后将n个小面积加起来,就近似的到总面积。
即定积分的近似值,当n越大,即区间分的越小,近似程度越高。
矩形法计算同梯形法。
流程:
建立主程序定义三个子程序分别调用三个子程序
执行
programsubject2_2
reala,b,s
integern
realrectangle,trapezip,sinpson
print*,"输入a,b,n的值"
read*,a,b,n
s=rectangle(a,b,n)
print10,a,b,n
print20,s
s=trapezip(a,b,n)
print10,a,b,n
print20,s
s=sinpson(a,b,n)
print10,a,b,n
print20,s
10format('a=',f5.2,3x,'b=',f5.2,3x,'n=',i4)
20format('s=',f15.8)
end
realfunctionrectangle(a,b,n)!
矩形法求解函数
implicitnone
realx,a,b,h,s
integeri,n
realfun
x=a
h=(b-a)/n
s=0
doi=1,n
s=s+fun(x)*h
x=x+h
enddo
rectangle=s
end
realfunctiontrapezip(a,b,n)!
梯形法求解函数
implicitnone
realx,a,b,h,s
integeri,n
realfun
x=a
h=(b-a)/n
s=0
doi=1,n
s=s+(fun(x+(i-1)*h)+fun(x+i*h))*h/2.0
enddo
trapezip=s
end
realfunctionsinpson(a,b,n)!
辛普生法求解函数
implicitnone
reala,b,h,f2,f4,x
integeri,n
realfun
h=(b-a)/(2.0*n)
x=h+a
f2=0
f4=fun(x)
doi=1,n-1
x=x+h
f2=f2+fun(x)
x=x+h
f4=f4+fun(x)
enddo
sinpson=(fun(a)+fun(b)+4.0*f4+2.0*f2)*h/3.0
end
realfunctionfun(x)
realx
fun=1+3*exp(x)+4/x+5
end
打印结果如下:
2-3,Gauss-Jordan法求联立方程组
矩阵:
A×B=C,C为要求解的未知数。
A=
,B=
,C=
思想:
(1):
利用动态数组定义一个矩阵行列数
(2):
利用上,下三角矩阵消元
programsubject2_3
real,allocatable:
:
a(:
:
),b(:
),c(:
)
print*,'输入未知数个数n'
read*,n
allocate(a(n,n))
allocate(b(n))
allocate(c(n))
print*,'输入系数矩阵a'
callinput(a,n)
print*,'输入等值矩阵b'
read*,b
print*,'联立方程组'
calloutput(a,b,n)
callgauss_jordan(a,b,c,n)
print*,'求解'
doi=1,n
print10,i,c(i)
enddo
10format('x',i1,'=',f8.4)
deallocate(a)
deallocate(b)
deallocate(c)
end
subroutineinput(a,n)
reala(n,n)
doi=1,n
read*,(a(i,j),j=1,n)
enddo
end
subroutinegauss_jordan(a,b,c,n)
dimensiona(n,n),b(n),c(n)
callup(a,b,n)
calllow(a,b,n)
forall(i=1:
n)
c(i)=b(i)/a(i,i)
endforall
end
subroutineoutput(a,b,n)
reala(n,n),b(n)
doi=1,n
print10,a(i,1),i
doj=2,n
if(a(i,j)>0)then
print20,a(i,j),j
else
print30,abs(a(i,j)),j
endif
enddo
print40,b(i)
enddo
10format(f5.2,'x',i1\)
20format('+',f5.2,'x',i1\)
30format('-',f5.2,'x',i1\)
40format('=',f8.4)
end
subroutineup(a,b,n)
reala(n,n),b(n)
doi=1,n-1
doj=i+1,n
p=a(j,i)/a(i,i)
a(j,i:
n)=a(j,i:
n)-a(i,i:
n)*p
b(j)=b(j)-b(i)*p
enddo
enddo
end
subroutinelow(a,b,n)
reala(n,n),b(n)
doi=n,2,-1
doj=i-1,1,-1
p=a(j,i)/a(i,i)
a(j,i:
n)=a(j,i:
n)-a(i,i:
n)*p
b(j)=b(j)-b(i)*p
enddo
enddo
end
打印结果:
总结:
Fortran95中基本思想
1,赋值:
用”=”连接,如x=0
2,定型:
整型(integer),实型(real),字符型(character),负型(complex),逻辑型(logicai),I-N规则,数组
3,函数
3,
4,排序:
1>交换法,2>选择法,3>冒泡法,
5,子程序的调用:
6,矩阵的引用:
上,下三角矩阵的转换(线性方程)
参考文献:
Fortran95课本