FORTRAN は、1950年代に開発された言語で、計算機言語としては、歴史が古い。進歩 の速い計算機に関しては、歴史が古いという事は、多くの場合、陳腐で劣る事を意味 する事が多い。事実、50年代或いはそれ以後開発された言語で、今日では使用されな くなった言語は非常に多い。そういった環境の中にあっても、FORTRAN は、色々な意 味で、優れた点を多く持った言語なので、様々な改良を加えられながら、今日まで、 科学計算用の標準的言語の一つとして、使われ続けている。その特徴としては、
FORTRAN を使って計算をしたい時には、FORTRAN の言語で書かれた一つのファイルを
先ず作らなければならない。こういったファイルをプログラムと呼ぶ。例として、球
の半径が与えられた時に、球の表面積と体積を求める計算を考えよう。そのためのプ
ログラムの例は、第2章で、エディタを使ってのファイル作成練習で書い
た、sphere.fである。念のため、下に掲げておこう
。
Program sphere
Implicit NONE
c constant:
Real PI
Parameter (PI=3.141593)
c local variable:
Real radius
Real area, volume
c begin:
radius = 10.0
area = 4. * PI * radius**2
volume = area * radius /3.
Write(*,*) 'radius:',radius
Write(*,*) ' surface area =',area,' volume =',volume
c end:
Stop
End
例.
a = 1.0
b = a + 1.0
| 演算 | FORTRAN | 例 |
| 加算 | x + y | |
| 減算 | x - y | |
| 掛算 | x * y | |
| 割算 | x/y | |
| 冪乗 | x**y | |
| 括弧 | (2.*(x + y))/(3.*(a + b)) |
Implicit NONE
Parameter (PI=3.141593)
がそうだ。最初の例は、そのプログラムで使用する変数は全て型宣言をしてから
使う事を宣言している。FORTRAN では、最初の文字によって、計算機が型を暗黙
のうちに解釈するという、便利なような恐ろしいような約束事がある。一見便利
なようなルールだが、プログラムを書き直したり、長いプログラムを書く時等、
使う変数をきちんと把握している方が、結局は便利である事の方が多い。
Implicit NONEをプログラムの頭で宣言しておくと、
型宣言していない変数をプログラム中で引用していたら、計算機が警告してくれる。
| 型 | FORTRAN | 大きさ |
| 整数型 | Integer |
|
| Integer*4 |
|
|
| 実数型 | Real |
|
| Real*8 |
|
|
| 複素数型 | Complex | (有効数字7桁) |
| Complex*16 | (有効数字15桁) | |
| 論理型 | Logical | .true.(真)或いは .false.(偽) |
| Logical*2 | ||
| 文字型 | Character*サイズ | サイズ分の長さの文字列 |
二番目の例のParameter文は、変数PIの値を指定している。式として 書いても同じ事だが、物理定数等このParameter文を用いて宣言すると、 値を直す時等、場所が決まっているから、便利である。
DIMENSIONの宣言は、良く使うであろう。
等を変数として、
使いたい時がある。この様な時、
DIMENSION y(10)
の様に宣言すると、y(1), ... , y(10) が使えるようになる。引数が
二次元ならば、
DIMENSION y(i,j)
の様にすれば良い。iとjは、それより前の
Parameter文でサイズを宣言して
おけば良い。
Write(*,*) 'radius:',radius
Write(*,*) ' surface area =',area,' volume =',volume
が、WRITE文である。'radius:'はradius:と表示させる事を意味し、
カンマに続くradiusは、変数radiusの値を表示させる事を意味している。
if (code.eq.1) then
...
else
...
end if
或いは次の様な更に細かい条件分岐も出来る。
if (code.gt.1) then
...
else if (code.eq.1) then
...
else
...
end if
y = 0.0
Do i=1,10
y = y + a(i)
End do
iが10以下である限り繰り返すといった場合には、次の様なDo whileが便
利だ。
i = 1
Do while (i.le.10)
y = y + a(i)
i = i + 1
End do
。
Program sphere2
Implicit NONE
c constant:
Real RADIUS_INITIAL,MAX_RADIUS,DELTA_R
Parameter(RADIUS_INITIAL=1.0,MAX_RADIUS=10.0)
Parameter(DELTA_R=2.0)
c local variable:
Real radius
Real area, volume
c begin:
radius = RADIUS_INITIAL
Do while (radius .le. MAX_RADIUS)
Call calculation(radius, area, volume)
Write(*,*) 'radius:', radius
Write(*,*) ' area =',area,' volume =',volume
Write(*,*)
radius = radius + DELTA_R
End do
Stop
End
Subroutine calculation(radius, area, volume)
Implicit NONE
c input:
Real radius
c output:
Real area, volume
c constant:
Real PI
Parameter (PI=3.141593)
c begin:
area = 4. * PI * radius**2
volume = area * radius /3.
Return
End
メインプログラムでは、半径を与えるだけで、計算はサブルーチンcalculation
で行っている。そしてメインプログラムとサブルーチンとの間のやり取りは、メイン
プログラム中のcall文で行う。その際、引数(radius,area,volume)は、
radius がメインプログラムから与えられ、areaとvolumeは、サブ
ルーチンから計算の結果として、メインプログラムに返される。
それぞれの引数の型は、メインプログラムとサブルーチンの間で必ず一致させなけれ
ばならない。但し、引数の名前は両者の間で異なっていても構わない。
この例に見るように、引数はメインプログラムからサブルーチンにも渡せるし、
逆にサブルーチンからメインプログラムにも渡せる。どちらからどちらに渡されてい
るかは、一見して明らかな訳ではないので、上のサブルーチンcalculationの
例のように、コメントで注釈を附けておくと、便利である。
また、サブルーチンから、別のサブルーチンを呼ぶことも出来る。
サブルーチンはReturnとEndで終わるのが約束である。
。
(サブルーチンcalculationは再掲していない。)
Program sphere3
Implicit NONE
c constant:
Real RADIUS_INITIAL,MAX_RADIUS,DELTA_R
c local variable:
Real radius
Real area, volume
c begin:
Write(*,*) 'Input RADIUS_INITIAL:'
Read(*,*) RADIUS_INITIAL
Write(*,*) 'Input MAX_RADIUS:'
Read(*,*) MAX_RADIUS
Write(*,*) 'Input DELTA_R:'
Read(*,*) DELTA_R
radius = RADIUS_INITIAL
Do while (radius .le. MAX_RADIUS)
Call calculation(radius, area, volume)
Write(*,*) 'radius:', radius
Write(*,*) ' area =',area,' volume =',volume
Write(*,*)
radius = radius + DELTA_R
End do
Stop
End
Read(*,*)が、端末から変数を読み込ませるときに用いる文である。
。
Program sphere4
Implicit NONE
c constant:
Real RADIUS_INITIAL,MAX_RADIUS,DELTA_R
c local variable:
Real radius
Real area, volume
c file open:
Open(Unit=2,File='Input.dat',Status='OLD')
Open(Unit=3,File='Output.dat',Status='NEW')
c begin:
Read(2,*) RADIUS_INITIAL,MAX_RADIUS,DELTA_R
radius = RADIUS_INITIAL
Do while (radius .le. MAX_RADIUS)
Call calculation(radius, area, volume)
Write(3,*) 'radius:', radius
Write(3,*) ' area =',area,' volume =',volume
Write(3,*)
radius = radius + DELTA_R
End do
Stop
End
(*,*)のところが(2,*)となったため、入力は2番の論理装置から行なわれ る。その2番の論理装置がInput.datという名前の既製のファイルである事を 最初のOpen文が記述している。 Write文が、(3,*)であるから、出力は 3番の論理装置に対してなされる。 二つ目のOpen文は、同様に3番の論理装置がInput.datという名前の の新規のファイルである事を記述している。
で、Read文が(2,*)ではなく、(2,*,end=900)となっている事に
注意しよう。これは、N回までDOループが回ろうとしているうちに、
読み込みデータがなくなったら、900番の文番号に飛ぶ事を意味している。
900番の文では、その時点での変数iを書き出すように命令しているから、
これにより、幾つデータを読んだかが判る。この様な場合、DO文は、途中で割
り込みが入ることになり、完結しないことに注意しておこう。
Program sphere5
Implicit NONE
c constant
Integer N
Parameter(N=2000)
c local variable:
Real radius
Real area, volume
integer i
c file open:
Open(Unit=2,File='Input.dat',Status='OLD')
Open(Unit=3,File='Output.dat',Status='NEW')
c begin:
Do i=1,N
Read(2,*,end=900) radius
Call calculation(radius, area, volume)
Write(3,*) 'radius:',radius,' area =',area,' volume =',volume
End do
900 Write(*,*) 'number of data=', i-1
Stop
End
このプログラムで、N以上読み込みデータがあると、number of data
として正しくない答えNを表示する。
| FORTRAN | 意味 | FORTRAN | 意味 |
| sqrt(x) | exp(x) | ||
| log(x) | log10(x) | ||
| sin(x) | asin(x) | ||
| cos(x) | acos(x) | ||
| tan(x) | atan(x) | ||
| sinh(x) | cosh(x) | ||
| tanh(x) | abs(x) | ||
| int(x) | float(n) | 整数 |
|
| max(x,y,z,...) | min(x,y,z,...) |
混合演算をしないように、と書いたが、実数xを整数に型変換するには、 int(x)を使い、整数xを実数に型変換するには、float(x)を 使う。
real function S(r)
implicit NONE
c constant:
real PI
parameter (PI=3.141593)
c local variable:
real r
c begin:
S=4.*pi*r**2
return
end
real function V(r)
implicit NONE
c constant:
real PI
parameter (PI=3.141593)
c local variable:
real r
c begin:
V=4./3.*pi*r**3
return
end
で定義して、メインプログラムからは、
Program sphere6
Implicit NONE
c constant:
Real RADIUS_INITIAL,MAX_RADIUS,DELTA_R
c local variable:
Real radius
Real area, volume, S, V
c begin:
Write(*,*) 'Input RADIUS_INITIAL:'
Read(*,*) RADIUS_INITIAL
Write(*,*) 'Input MAX_RADIUS:'
Read(*,*) MAX_RADIUS
Write(*,*) 'Input DELTA_R:'
Read(*,*) DELTA_R
radius = RADIUS_INITIAL
Do while (radius .le. MAX_RADIUS)
Write(*,*) 'radius:', radius
area =S(radius)
volume=V(radius)
Write(*,*) ' area =',area,' volume =',volume
Write(*,*)
radius = radius + DELTA_R
End do
Stop
End
のように、外部関数を使う。FUNCTION 文は、メインプログラムの後ろにつけて、コン
パイルするのが良いだろう
。
浦 昭二: FORTRAN入門(3訂版)(培風館)
森口繁一:JIS FORTRAN入門(第3版)上・下 (東大出版会)