Fortran Coder

查看: 11587|回复: 8

[通用算法] 彭国伦---《Fortran95程序设计》----------纠错

[复制链接]

66

帖子

5

主题

2

精华

版主

院士级水师

F 币
481 元
贡献
273 点

管理勋章帅哥勋章爱心勋章规矩勋章

QQ
发表于 2014-4-17 19:55:03 | 显示全部楼层 |阅读模式
今天拜读彭国伦老师的经典著作《Fortran95程序设计》一书,偶然发现第十一章中ex1108.F90有点小错误,在这里指出来,供后面阅读的朋友借鉴。
首先要说是著书立学是一件很不容易的事情,任何一本书都难免会有失误(据说《毛泽东语录》没有失误)。彭国伦老师的《Fortran95程序设计》一书作为Fortran初学者入门必读的经典著作,指引我进入Fortran语言的殿堂,可谓是我的启蒙老师,对于她的价值,我是持完全肯定的。无论现在还是将来我都会认为她是一本难得的经典著作。
其次,感谢群主---臭石头雪球大哥对我的支持,对你的Fortran编程水平我一直是很膜拜的,但是最难能可贵的是你一直不厌其烦的回答群友的问题,让我在Fcode中找到了难得的归属感,当然对于群中可爱的群友们在这里也一并表示感谢了。
下面开始正文,彭书331页、EX1108.F90是一个实现:自定义时间类型;完成自定义时间类型与实数相加;实数与自定义时间类型相加;时间类型之间互相比较大小的程序。出问题的地方在于时间类型互相比较大小时的子程序,原程序如下所示:
[Fortran] 纯文本查看 复制代码
logical functiontime_lt_time( a, b )
    implicit none
   type(time), intent(in) :: a,b
      if (a%hour < b%hour ) then
      time_lt_time = .true.
      return
     end if
     if (a%minute < b%minute ) then
     time_lt_time = .true.
      return
      end if
     time_lt_time = .false.
       return
  end function
按照主程序中输入的变量值
[Fortran] 纯文本查看 复制代码
a=0.5  ! a =time(0,30)
b=0.1+a       ! b = time(0,36)
write(*,*)a<b
按照书上的数据程序可以得到正确的结果,但是子程序中隐含着一个错误,先让我们来看看子程序是怎么工作的,进而来指出这个错误:
走上来是先判定a变量的小时数是否小于b变量的小时数,成立则time_lt_time为T,判断结束,否则(a%hour>=b%hour)进入第二个if判断,a的分钟数是否小于b的分钟数,如果a的分钟数小于b的分钟数则time_lt_time = .true.结束第二个if判断。至此细心的你是不是发现问题的所在了那?执行第二个if判断的前提是a%hour>=b%hour,此时如果我的a%hour>b%hour,结果应该是已经确定的了,time_lt_time = .False.第二个if本就不必再执行,而且若是a%minute<b%minute则原程序第二个if判断会给出错误的结果。因此这个子程序并不能正确的完成比较大小的任务。
建议修改为:
[Fortran] 纯文本查看 复制代码
logical functiontime_lt_time( a, b )
    implicit none
   type(time), intent(in) :: a,b
    if (a%hour < b%hour ) then
     time_lt_time = .true.
     return
   end  if 
    if ( a%hour==b%hour.and.a%minute < b%minute ) then
     time_lt_time = .true.
     return
   end if
    time_lt_time =.false.
   return
  end function
即在第二个if判断条件中加入条件a%hour==b%hour,经测试修改后的程序可以正确的实现判断功能。

评分

参与人数 1F 币 +20 贡献 +10 收起 理由
fcode + 20 + 10 赞一个!

查看全部评分

科研穷三代,读博毁一生

2010

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1548 元
贡献
666 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

发表于 2014-4-17 20:01:27 | 显示全部楼层
嗯,小鱼看书很认真。以前都没发现这个错误来。

我有一个很简单,很直观的写法:

[Fortran] 纯文本查看 复制代码
  logical function time_lt_time( a, b )
    implicit none
	  type(time), intent(in) :: a,b
    time_lt_time = ( ( a%hour < b%hour ) .or. ( (a%hour==b%hour).and.(a%minute<b%minute) ) )   
  end function

38

帖子

7

主题

0

精华

熟手

F 币
218 元
贡献
134 点

规矩勋章

发表于 2014-4-17 20:05:14 | 显示全部楼层
群里看你讨论了,你很有心啊,学习了

136

帖子

3

主题

0

精华

版主

F 币
1964 元
贡献
1677 点

帅哥勋章管理勋章爱心勋章新人勋章热心勋章元老勋章

发表于 2014-4-17 20:59:31 | 显示全部楼层
大牛也免不了出错啊~ 哈哈

66

帖子

5

主题

2

精华

版主

院士级水师

F 币
481 元
贡献
273 点

管理勋章帅哥勋章爱心勋章规矩勋章

QQ
 楼主| 发表于 2014-4-19 14:56:33 | 显示全部楼层
fcode 发表于 2014-4-17 20:01
嗯,小鱼看书很认真。以前都没发现这个错误来。

我有一个很简单,很直观的写法:

霸气威武的写法,学习了。
科研穷三代,读博毁一生

31

帖子

5

主题

0

精华

入门

F 币
105 元
贡献
54 点
发表于 2014-7-22 14:20:56 | 显示全部楼层
感觉第143页EX0714中第七行和第九行的注释错了,第七行为下三角,第九行为上三角,如果我说错了,勿喷。

评分

参与人数 1F 币 +5 贡献 +5 收起 理由
fcode + 5 + 5 赞一个!

查看全部评分

2010

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1548 元
贡献
666 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

发表于 2014-7-23 07:09:29 | 显示全部楼层
FLY 发表于 2014-7-22 14:20
感觉第143页EX0714中第七行和第九行的注释错了,第七行为下三角,第九行为上三角,如果我说错了,勿喷。 ...

这个没有错哦。Fortran 是列优先的,所以 a(i,j) 一般称呼 I 为 列,J 为 行,即第 J 列,第 I 行。
I>J 时,列数比行数大,是上部分。
I<J 时,列数比行数小,是下部分。

31

帖子

5

主题

0

精华

入门

F 币
105 元
贡献
54 点
发表于 2014-7-23 10:20:10 | 显示全部楼层
fcode 发表于 2014-7-23 07:09
这个没有错哦。Fortran 是列优先的,所以 a(i,j) 一般称呼 I 为 列,J 为 行,即第 J 列,第 I 行。
I>J  ...

额,我还是有一些疑问。个人理解:
     a(i,j)中,i表示的行,j表示的列,fortran中列优先指的是在内存里储存数据的时候按照第一列、第二列的顺序储存,比如对于a(5,5)这个数组按照a(1,1),a(2,1).....a(5,1),a(2,2)...a(5,2)...这样的顺序储存的。所以i表示的行,j表示的列,i>j,下半部分啊。而且在矩阵论里面不也是这样来定义的么?
     求解答。
   

31

帖子

5

主题

0

精华

入门

F 币
105 元
贡献
54 点
发表于 2014-7-23 10:25:35 | 显示全部楼层
第455页中,逆阵的求解的结果感觉有点不对,逆阵中第二行第一列-0.63应该是-0.063,最后一行最后一列-0.63也应该是-0.063。我用的MKL中sgetrf和sgetri函数算出来是这个结果
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-10-10 15:10

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表