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
つづく