PP#7~Fortran Tips#2
第二回テーマは文字列を数値型に変換するC/C++関数「atof」の作成です。
3種類のサブルーチンを作成しました。最も単純なType 1は一行。最も凝ったType 3は技術屋好みの全て一から手作りです。Defaultは計算時間が最もかからないType 1に設定していますが、お好みでどうぞ。因みに、全て倍精度計算になっています。
なお、Type 2でフォーマットサイズを99.90に仮置きしていますが、これぐらいの大きさを見ておけば良いだろうという感覚的なものですので、念為。
real*8 function atof(String)
!************************************************************************
!* Convert String to Double Precision Value *
!************************************************************************
implicit none
character,intent(in):: String*(*)
integer:: countTot, countInt, countDec, count, kount, ck, &
dot, digit, atoi, Option
real*8:: atofi
character:: outbuf*2, form*8 = '(f99.90)'
!========================================================================
Option = 1 !preset
select case(Option)
case(1) !Type 1
read(String,*) atof
!print *,"atof1= ",atof
case(2) !Type 2
!count dot digit
dot = max (1, index(String, '.'))
countTot = len(trim(String))
countInt = max(1, dot - 1)
countDec = max(1, countTot - dot)
write(outbuf, '(i2)' ) countTot; form(3:4) = outbuf
write(outbuf, '(i2)' ) countDec; form(6:7) = outbuf
read(String,form) atof
!print *,"atof2= ",atof
case(3) !Type 3
!count dot digit
dot = max (1, index(String, '.'))
countTot = len(trim(String))
countInt = max(1, dot - 1)
countDec = max(1, countTot - dot)
!Conver interger character to value
atoi = 0
do count=1,countInt
if (String(count:count) >= '0' .and. String(count:count) <= '9') then
read(String(count:count),*) digit
atoi = 10*atoi + digit
endif
enddo
!Conver decimal character to value
atof = 0.0
kount = 1
do count=dot+1,countTot
atofi = 1.0
do ck=0,kount-1
atofi = 0.1*atofi
enddo
read(String(count:count),*) digit
atof = atof + digit*atofi
kount = kount + 1
enddo
atof = atof + dble(atoi)
!print *,"atof3= ", atof
end select
!========================================================================
end function
以下のように呼び出して使います。
program call_atof
!********************************************************************************
!* call_atof *
!********************************************************************************
implicit none
integer,parameter::fin = 5
integer,parameter::LINEMAX = 130
character(len=LINEMAX)::inkey
!================================================================================
do
call getline(fin, inkey)
print '("Key to be input (/ to exit)= ", a)', inkey
if (inkey == '/') exit
print '("Key to be output = ",f99.90)', atof(inkey)
enddo
print '("Reached end of program")'
!================================================================================
stop
!================================================================================
contains
!================================================================================
real*8 function atof(String)
-----------------------
end function
end program
つづく