PP#7~Fortran Tips#2

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

つづく

Comments are closed.