Fortran 实用编程 系列视频教程 Fortran Coder 研讨团队 http://www.fcode.cn
关于 Fortran Coder Fortran Coder 始于2006年,是一个以科学计算编程为主题的非盈利性研讨团体。大多数由各行业高等学府学生,研究人员及生产一线的工作人员组成。 研讨内容涉及:Fortran77/90/95/2003/2008语法规范,各平台32位及64位编译器,IMSL,MKL,Lapack 等数学函数库,MPI,OpenMP,Coarray 并行及高性能计算,winteracter / DisLin / Matfor / GTKFortran 等绘图及界面库。
关于本套视频 本套视频以解决实际问题为主要目的,旨在为您解答课本上较少涉及到的实际问题。通过本套视频,您会更容易了解: 如何查找错误?如何解决错误? 如何学习 Fortran2003 和 Fortran2008 语法? 如何用最通俗易懂的写法解决实际问题? 如何看懂别人的优秀代码并为自己所用?如何让自己的代码更优美、更普适? 本套视频由 Fortran Coder 研讨团队录制,供所有 Fortran 程序员和学习者免费自由的观看,您可随意的传播它。但请保证视频完整性。 我们将会不定期的更新本套视频,请持续关注我们的网站、QQ群! 同时,如果您对 Fortran 相关有自己的见解,并愿意通过录制视频的方式与其他人分享,请联系我们!
Fortran 代码有固定格式和自由格式。建议使用后者,能看懂前者。 上节要点回顾 Fortran 代码有固定格式和自由格式。建议使用后者,能看懂前者。 程序的基本单元构成: 字符->Token->语句->程序单元->模块->程序 程序单元是程序的基本单位,程序通过多层次的调用不同的彼此独立程序单元实现复杂的过程。 语句有三种:声明语句、执行语句和结构语句 我们建议显式声明所有变量。并使用 Implicit None 语句 声明变量有多种方式,历史遗留了很多不便于阅读和理解的方式,建议更新成新的声明方式。
语法之数据类型与浮点数 第五讲 讲解人:雪球 gao@fcode.cn http://www.fcode.cn 讨论QQ群:2338021 基础篇 第五讲 语法之数据类型与浮点数 讲解人:雪球 gao@fcode.cn http://www.fcode.cn 讨论QQ群:2338021
目 录 1 数据类型 2 Kind 3 整型和字符型 4 浮点数
数据类型 计算机里只有 1 和 0 两种状态,任何数据都是 1 和 0 的组合! 为了把 1 和 0 的组合与人类习惯的数据关联起来,人们规定了很多“法则”。 采用不同“法则”对应的数据,就是不同的数据类型 7 00000111 0100001001001010 0000000000000000 50.5 IEEE IBM 中国 ASCII Unicode 0xD6D0B9FA mp3、wav、 bmp、jpg、rmvb、avi
long 0x636F6465 数据类型 长、始终、渴望 龙、笼、隆、笼 code 1668244581 6.7422143E+022 计算机往往只存储数据,并不说明数据的类型! 这就可能对同一个数据产生不同的解释。 为了避免这种情况,我们的编译器可以帮助我们管理数据类型!
Fortran 标准数据类型: 数据类型 Integer(Kind=??) :: 整型 Real(Kind= ?? ) :: 实型 / 浮点型 Complex(Kind=??) :: 复数型(两个实型的组合) Logical(Kind=??) :: 逻辑型 / 布尔型 Character(Kind=1,len=??) :: 字符型 Type( ?? ) :: 派生类型(上述类型的组合)
数据类型 数据除了有类型之外,还有一定的属性。他们用定义时的形容词来赋予。 Real , parameter :: PI = 3.141592654
目 录 1 数据类型 2 Kind 3 整型和字符型 4 浮点数
Kind Kind 的正式名称叫“种别”,是区分同一种数据类型,但不同长度、或精度、或编码方式的一种代号。他在编译时决定! 对 Integer ,Kind 值影响整数能表达的最大范围 对 Real 和 Complex, Kind 值影响实数的最大范围和最小精度 对 Character ,Kind 值表示编码。通常为 ASCII 编码 对 Logical , Kind 值表示长度,对逻辑型无影响。
Kind Integer 的 Kind,常见 1、2、4、8 等 对于大多数编译器,Kind 默认是 4,占有 4 个字节 超短整型 -(2^7) -128 2^7 -1 127 0x37 2 短整型 -(2^15) -32768 2^15-1 32767 0x3701 4 整型 长整型 -(2^31) -2147483648 2^31-1 2147483647 0x37010ab2 8 超长整型 -(2^63) -9223372036854775808 2^63-1 9223372036854775807 23c38e7f 对于大多数编译器,Kind 默认是 4,占有 4 个字节 但大多数编译器也允许调整默认Kind值 并不是所有编译器都允许1、2、4、8的Kind值。 某些编译器不支持Kind=8, Kind=1 ,而某些编译器用1、2、3、4 表示
Kind k = Selected_Int_Kind( i ) 可以用这个函数来选择能满足要求的Kind i 表示需要最大的十进制位数 k 表示返回的能满足范围的最小的Kind值
Kind Real 的 Kind,常见 4、8、16 等 对于大多数编译器,Kind 默认是 4,占有 4 个字节 实型 3.4028235E+38 1.1754944E-38 0x37010ab2 8 双精度 1.7976931E+308 2.2250738E-308 22222222 16 四精度 1.1897314E+4932 3.3621031E-4932 33333333 44444444 对于大多数编译器,Kind 默认是 4,占有 4 个字节 但大多数编译器也允许调整默认Kind值 并不是所有编译器都允许4、8、16的Kind值。 某些编译器不支持Kind=16 ,而某些编译器用1、2、3 表示
Kind k = Selected_Real_Kind( r , p ) 可以用这个函数来选择能满足要求的Kind k 表示返回的能满足范围的最小的Kind值
Kind Complex 的数据类型与 Real 一致。 但需要注意的是: 如果 Kind=8 的 Real 占用 8 字节,则 Kind=8 的 Complex 占有 16 字节 很多人使用 Complex(Kind=16) 来定义双精度,实际上,这已经是四精度了。 Complex 选择Kind,也使用 Selected_Real_Kind 函数
Kind Character 的 Kind,常见只有一种,即 1 表示 ASCII 编码 通常忽略 Character( Kind=1 , Len=32 ) :: cStr Character( Len=32 ) :: cStr Character :: cStr 也可以使用 Selected_Char_Kind 来选择。 k = Selected_Char_Kind( 'ASCII' ) Character( Kind=k , Len=32 ) :: cStr
Kind Logical 的 Kind,通常与该编译器支持的 Integer 一致 通常忽略,在大多数编译器上,Kind=4,占有4字节
目 录 1 数据类型 2 Kind 3 整型和字符型 4 浮点数
整型和字符型 整型是最自然的表达。 一些语法中表示次数(循环变量),个数(数组下标),Kind值本身也是整型!包括内存地址也是整数。 需要注意整型变量的最大范围,尤其在阶乘、指数等可能产生较大数据的计算中,必须预先做出评估 其次注意,整型和整型的计算结果依然是整型! 例如 1/2 = 0 ; 3/2 = 1 但整数和浮点数的计算结果一般是浮点数,例如 1/2.0 =0.5 尽管如此,我们依然推荐在浮点数的表达式中,尽量把常数写成浮点数
整型和字符型 字符型是最接近人类语言的表达 需要注意字符串定义时必须有长度,且通常是固定的。 Fortran的字符串没有结束符 \0,所以在字符串操作中,必须注意! 有必要时需实用 trim 去除尾部空格 可通过内部文件在字符串和整型、实型间相互转化。 read( 字符串 , * ) 整型或实型变量 字符串->数字 write( 字符串 , * ) 整型或实型变量 数字->字符串
整型和字符型 字符型允许使用“子字符串”表示字符串的一部分 character(len=12) :: c = "www.?????.cn" c( 5 : 9 ) = "fcode" !// 此时 c="www.fcode.cn" c( : 3 ) = "bbs" !// 此时 c="bbs.fcode.cn" c( 10 : ) = "" !// 此时 c="bbs.fcode___" 灵活运用子字符串可以让很多事情事半功倍
整型和字符型 语法中,有很多内容本身也是字符串。 例如文件名,Open语句的子句,格式format
目 录 1 数据类型 2 Kind 3 整型和字符型 4 浮点数
计算机资源是始终有限的,永远也无法准确的描述无穷的实数 浮点数 计算机资源是始终有限的,永远也无法准确的描述无穷的实数 在数值计算中,误差总是存在的!
浮点数 定点数 浮点数 10.0/3 = 3.33 元? 现实生活中,其实也有很多用有限数据来表征无限可能的例子,他们也有误差: 0.5 0.25 10.0/3 = 3.33 元? 0.5 0.75 0.6 ?
浮点数 实型 Real 复数型 Complex 实数 复数 浮点数
浮点数 计算机中浮点数的规则有很多,其中应用最多的是 IEEE 标准。其他的如IBM标准。 正如我们用科学计数法表达实数一样,计算机也使用二进制的科学计数法表达实数。 我们来演示一下 IEEE 浮点规则: 0x424A0000 01000010010010100000000000000000 它也由三部分组成: a. 符号(0:+ 1:-) b. 有效数 10010100000000000000000 c. 指数 10000100 +6.022141290E+23 它由三部分组成: a. 符号(+或-) b. 有效数 6.022141290 c. 指数 E+23
R=(-1)**0*(1+0.578125)*(2**5) = 50.5 浮点数 0x424A0000 符号位为 0 ,表示是正数(否则是负数)。 有效数 10010100000000000000000 第一位表示 1/2,第二位表示 1/4,第三位表示 1/8 .... 取为 0 则不计入总数,取为 1 则计入总数 所以有效位:1/2 + 1/16 + 1/64 = 0.578125 参与计算时,再加 1。 指数位 1000100,对应十进制的 132,它并不直接计算,而是使用与 127 的差值,即 132-127 = 5。 参与计算时,做为 2 的指数。 0x424A0000 01000010010010100000000000000000 三部分: a. 符号(0:+ 1:-) b. 有效数 1001010000... c. 指数 10000100 R=(-1)**0*(1+0.578125)*(2**5) = 50.5
223 = 10x 252 = 10x 浮点数 x = log(223) = 6.923 0x424A0000 x = log(252) 除非恰好能被 2**(-n) 线性组合出来的数,比如 1.5、1.75 ,用浮点数表达不存在误差,绝大多数浮点数都是有误差的!例如 1.6 就有误差 那么浮点数到底有多少误差呢? 单精度: 223 = 10x x = log(223) = 6.923 0x424A0000 01000010010010100000000000000000 a. 符号(0:+ 1:-) 1 b. 有效数 1001010000... 23 c. 指数 10000100 8 双精度: 252 = 10x x = log(252) = 15.35
浮点数 由于浮点数存在误差,因此,我们应该尽量避免以下操作: 1. 对浮点数进行相等判断! if ( a == 1.3 ) => if( abs(a-1.3)<1.0e-5 ) 2. 用浮点数做为数组角标! b = a(2.0) => b = a(2) 3. 用浮点数做为循环变量! Do r = 0.0 , 2.0 , 0.1 => Do i = 0 , 20 r = i / 10.0
a = L * tan(x) ; a = x ** 3 ; !// 放大误差 累加 !// 积累误差 浮点数 在绝大多数科学用数值计算中,我们并不害怕误差! 而是害怕误差的放大和积累! a = L * tan(x) ; a = x ** 3 ; !// 放大误差 累加 !// 积累误差 因此,设计合理的、健壮的算法,对于数值计算尤其重要!
感谢收看! Fortran Coder Group http://www.fcode.cn 下一讲:流程控制 敬请关注 & 期待 还有疑问?请联系我们 Fortran Coder Group http://www.fcode.cn