Locked History Actions

FORTRAN

FORTRAN

MEMO

  • C 言語の break, continue に相当するのは、 EXIT と CYCLE 。g77 で使える。COMIS では使えないかも?(参考: http://denki.nara-edu.ac.jp/~yabu/soft/fortran.html)

    •         DO i = 1,10
                 WIRTE(*,*) 'Here 1'
                 IF (i .EQ. 5) CYCLE
                 WIRTE(*,*) 'Here 2'
              ENDDO
      
              DO i = 1,10
                 IF (i .EQ. 5) EXIT
              ENDDO
  • pgf77 -> g77

  • 残存文字を取得する書式指定子 Q は g77 では使えない。
    •    1         read(5,500) ichar,ia
         2 500     format(q,i10)
         3         if (ichar .eq.0) then
         4             write(*,*) 'Enter'
         5         else
         6             write(*,*) 'value:', ia
         7         endif
      
    • pgf77 では、上記のようなコードで、エンターが入力されたのか、そうでないのかを判定することができる。エンターの場合 ichar が 0。数値の場合、ichar > 0。

    • しかし、g77 では Q が使えないので、以下のようなコードにする。一旦、文字列として読み込み、そのあと数値に変換している (参考: fortran 備忘録)。

    •    1         character(10) ans
         2         read(5,'(a)') ans
         3         if (len_trim(ans) .eq.0) then
         4             write(*,*) 'Enter'
         5         else
         6             read(ans,*) ia
         7             write(*,*) 'value:', ia
         8         endif
      
    • 以下の pgf77 のコードは、g77 のその次のコードに書き換えられる。
    •    1         subroutine wrtmsg(text)
         2         logical*1 text(80)
         3 
         4         nchar=0
         5         do 10 i=1,80
         6         if(text(i).eq.0) go to 20
         7 10      nchar=nchar+1
         8 20      write(6,600) (text(k),k=1,nchar)
         9 600     format(<nchar>a1)
        10         return
        11         end
      
    •    1         subroutine wrtmsg(text)
         2         character(*) text
         3 
         4         write(6,*) text
         5         return
         6         end
      
  • pgf77 の H 形編集記述子 は g77 でも使える。しかし、そもそも H 形編集記述子 はわかりにくい。write 文でうまく工夫した方が良さそう (参考: H 形編集記述子)。

    •    1       write(*,'(4hTEST,a)')   'test'
         2       write(*,'(a,a)') 'TEST','test'
         3       write(*,*)       'TEST','test'
      
    • 出力
    • TESTtest
      TESTtest
       TESTtest
  • コンパイラ、及び 32bit, 64bit システム の依存性
    • 次のプログラムをコンパイルして実行する場合、結果が異なる。
    •    1       program main
         2       real*8 a,b
         3       integer n
         4       a=1.0d0
         5       b=0.1d0
         6       n=a/b
         7       write(*,*) 'a=',a
         8       write(*,*) 'b=',b
         9       write(*,*) 'n=',n
        10       end
      
    • コンパイルと実行は以下のように行った。
    • > g77 -o test test.f
      > ./test
      > gfortran -o test test.f
      > ./test
      > pgf77 -o test test.f
      > ./test 

32 bit

64 bit

g77

a= 1.
b= 0.1
n= 9

a= 1.
b= 0.1
n= 10

gfortran

a= 1.00000000000000
b= 0.100000000000000
n= 9

a= 1.0000000000000000
b= 0.10000000000000001
n= 10

pgf77

a= 1.000000000000000
b= 0.1000000000000000
n= 10

a= 1.000000000000000
b= 0.1000000000000000
n= 10

  • READ 文
  •       ~~~~~~
          OPEN (UNIT=90, FILE=fname, STATUS='old', ERR=999)
          READ(90,600,END=998) (prm(i),i=1,5),(power(i),i=1,6)
    600   FORMAT(5G14.6, 2X, 6I1)
    998   CONTINUE
          RETURN
    999   WRITE(*,*) 'Cannot open file!'
          RETURN
    • READ(90,600,END=998) の 90 は Logical unit number(LUN)、600 は FORMAT文の書いてある文番号、END=998 はファイルを読み終えた場合に飛ぶ文番号。
    • FORMAT(5G14.6, 2X, 6I1) は以下のような書式のファイルを読んでいる。5G14.6 のGは データの大きさによって表記が変わる混合型。参考 : FORMAT文(数値) - G型変換

      0.917467E+00 -0.187210E-01  0.            0.           -0.316630E-01  100000
    • つまるところ、以下のように値が入る。
      • prm(1) = 0.917467E+00
      • prm(2) = -0.187210E-01
      • prm(3) = 0.
      • prm(4) = 0.
      • prm(5) = 0.
      • power(1) = 1
      • power(2) = 0
      • power(3) = 0
      • power(4) = 0
      • power(5) = 0
      • power(6) = 0
  • 無限ループ
  •   DO WHILE (.TRUE.)
      ENDDO
  • 組み込み関数 len_trim

SUBROUTINE

  • SUBROUTINE の名前を SUBROUTINE の引数にすることができる。引数の数と型が同じいくつかの SUBROUTINE を呼び出す場合に使う。
  •    1       program main
       2       implicit none
       3 
       4       external sub1
       5       external sub2
       6 
       7       call call_sub(1,sub1)
       8       call call_sub(2,sub2)
       9 
      10       return
      11       end
      12 
      13       subroutine call_sub(i,subname)
      14       implicit none
      15       integer i
      16       call subname(i)
      17       return
      18       end
      19       
      20       subroutine sub1(i)
      21       implicit none
      22       integer i
      23       write(*,*) 'sub1, i=',i
      24       return
      25       end
      26 
      27       subroutine sub2(i)
      28       implicit none
      29       integer i
      30       write(*,*) 'sub2, i=',i
      31       return
      32       end