TGDZ Calc的Fortran90实现

我大学时学的是Fortran77,当时完全没有计算机的概念,一上来就学这个语言编程,很多编程的概念都没有建立起来,几年之后就完全忘光了.
今天拿起Fortran想把TGDZ Calc重新写一遍,又临时找了本FORTRAN教程来看,才发现当年的FORTRAN77真是憋屈的一个语言,用的是固定格式,语言中的一些设定也非常奇葩(比如“某某字母开头的代表是整形变量”,开头必须是数字以代表一行,多少列之后的字符会被忽略), 完全没有想再学一下的兴趣,于是直接跳到采用自由编码格式的Fortran90.
搞了一会儿,才明白subroutine之外还有function,前者大约相当于模块或其它源文件,后者则与现代的函数有点类似,有意思的是,f90中参数只读用indent 指令来限制,参数的类型不写在括号内而是放在函数内部的前面(这可能与当时的语法分析能力不足有关).F90的参数传地址,可以将函数作为参数传统等特点,又感觉有一点高级.这个东西对字符串的支持感觉比较少,连中文字串都容易乱码.

更奇葩的是,在测试中我发现有一行代码中,声明变量时并进行了初始化,但调试时发现根本就没有执行这个初始而导致出现了奇怪的错乱,可能是编译器的某个bug.

总体感觉下来,这是一个非常早期的语言,语法上很不灵活,主要限制在一些理工科计算的领域还在使用,在通用领域远不如C或C++等语言好用. 感觉如果要用的话,可以用它写一些基本的计算库,给C++来调用会比较好.

点击查看代码
program main
implicit none
!declare function returned value
character(len=4),external::YearToTGDZ
integer,external::CalcBaseYear, TGDZtoYear
character(len=4)::CalcedTGDZ
integer:: year, bYear, reCalcedYear
integer, parameter:: LastYear=2100

do year=1900, LastYear
bYear= CalcBaseYear (year)
CalcedTGDZ=YearToTGDZ(year)
reCalcedYear=TGDZtoYear(CalcedTGDZ, bYear)
print *, year, " --> ", CalcedTGDZ," start from ", bYear, ",reversed to ", reCalcedYear
end do

end


integer function CalcBaseYear(cy)
implicit none
 integer,intent(in):: cy
 integer:: by

  if (cy >0) then
by=4
 else
by=-57
 end if

do while (by > cy)
by = by -60
end do

do while( (by+60) <=cy)
by = by+ 60;
end do
CalcBaseYear=by
return
 end


character(len=4) function YearToTGDZ(y)
 implicit none
 integer,intent(in)::y  ! describle the param
 integer::tmpyear,offval, tgi, dzi ! define local variables
character(len=2):: tgArr(10), dzArr(12)
tmpYear=y  ! copy the value

tgArr(1)="甲"
tgArr(2)="乙"
tgArr(3)="丙"
tgArr(4)="丁"
tgArr(5)="戊"
tgArr(6)="己"
tgArr(7)="庚"
tgArr(8)="辛"
tgArr(9)="壬"
tgArr(10)="癸"
dzArr(1)="子"
dzArr(2)="丑"
dzArr(3)="寅"
dzArr(4)="卯"
dzArr(5)="辰"
dzArr(6)="巳"
dzArr(7)="午"
dzArr(8)="未"
dzArr(9)="申"
dzArr(10)="酉"
dzArr(11)="戌"
dzArr(12)="亥"

 if (tmpyear>0) then
 offval=4
 else
 offval=3
 end if

 tmpyear = tmpyear - offval

 do while(tmpyear<0)
 tmpyear=tmpyear+60
 end do

 tgi= mod(tmpyear,10)
  dzi=mod(tmpyear,12)
YearToTGDZ=tgArr(tgi+1)//dzArr(dzi+1)
return
 end

integer function TGDZtoYear ( tgdzChars, givenBY)
implicit none
 character(len=4),intent(in)::tgdzChars
 integer,intent(in)::givenBY
 integer::ti, di, m ! init ti=1 or di=1 sometimes is ingnored, wield!
 character(len=2):: tgChar, dzChar
 character(len=2):: tgArr(10), dzArr(12)
 ti=1  ! Clearly set ti to 1 for each call
 di=1
tgArr(1)="甲"
tgArr(2)="乙"
tgArr(3)="丙"
tgArr(4)="丁"
tgArr(5)="戊"
tgArr(6)="己"
tgArr(7)="庚"
tgArr(8)="辛"
tgArr(9)="壬"
tgArr(10)="癸"
dzArr(1)="子"
dzArr(2)="丑"
dzArr(3)="寅"
dzArr(4)="卯"
dzArr(5)="辰"
dzArr(6)="巳"
dzArr(7)="午"
dzArr(8)="未"
dzArr(9)="申"
dzArr(10)="酉"
dzArr(11)="戌"
dzArr(12)="亥"
tgChar=tgdzChars(1:2)
dzChar=tgdzChars(3:4)
!print *, tgchar
!print *, dzchar

! Calc the tgindex
do while(ti<=10)
if (tgArr(ti)==tgChar) then
exit  ! ti is the target result
end if
ti=ti+1
end do


!Calc the dzIndex
do while(di<=12)
if (dzArr(di)==dzChar) then
exit   ! when exit ti is the result
end if
di=di+1
end do

m=ti - di
if (m<0) then
m=12+m
end if
! use the function name to return the result value
TGDZtoYear=givenBY + 5*m + ti-1 ! ti is 1-based index, so sub 1 from result.
return
 end

! Coded and debuged in Simply Fortran 3.40 build 4419, compiler is bundled gfortran.

posted @ 2025-05-23 18:18  dingxianghuan  阅读(24)  评论(0)    收藏  举报