コンテンツにスキップ

「Fortran」の版間の差分

出典: フリー百科事典『ウィキペディア(Wikipedia)』
削除された内容 追加された内容
Point136 (会話 | 投稿記録)
m Bot:rdr プリンタ
5HPONGO (会話 | 投稿記録)
171行目: 171行目:


==== 数など ====
==== 数など ====
* [[文字列]]を指定するのに、[[アポストロフィー|アポストロフィ]](<nowiki>'</nowiki>)が使えるようになった。
* [[文字列]]を指定するのに、[[アポストロフィー|アポストロフィ]](<nowiki>'</nowiki>)が使えるようになった。例えば<nowiki>'FORTRAN'</nowiki>


==== 変数など ====
==== 変数など ====

2008年7月22日 (火) 22:01時点における版

FORTRANフォートランFORmula TRANslationの略)は、1954年IBMジョン・バッカスによって考案された、コンピュータにおける史上初の高水準記述言語である。IBM 704向けに最初に作成された。

科学技術計算に向いた、逐次型手続き型言語である。2008年現在でも使われ続けており、その仕様は初期の頃と比べればかなり拡張されたものとなってきている(初期の頃は、変数名が大文字6文字までで、動的な記憶領域の確保ができないなどの制約があった)。

なお、大文字でFORTRANと表記した場合、FORTRAN 77以前のFORTRANを指し、Fortranと表記した場合、Fortran 90以降を指すことがある。

FORTRANの特徴

ここでは、広く使われていたFORTRAN 77までのプログラミング言語の特徴について概要を記す。

数式を簡便に書ける
ほぼ数学の数式通りに計算式を記述できる。もっともこの特徴は他に計算向きの高級言語がなかった時代の話であり、現代の水準では「プログラミング言語における標準数式表現の始祖」といった方が当たっている。
出力が容易
簡単に出力形式を定義できるFORMAT文や、実際の出力デバイスを意識しないで済む入出力文がある(C言語標準入出力と似た概念である)。
スタック指向/構造化指向の言語ではない
COMMON文、BLOCK DATA文やSAVE文(FORTRAN 77)など、データを固定的に割り当てることを前提としている。
固定形式の書式である
記述方法がカラム位置で決まっている(一部の実装では拡張されている)

初期のFORTRAN

初期のFORTRANは、IBM 704計算機用に作られ、4つのタイプがあった。

FORTRAN I
最も基本的なFORTRAN
FORTRAN II
FORTRAN I に副プログラム呼び出しの機能を付加したもの。
FORTRAN III
FORTRAN II に若干の改良を行なったもの。bool演算機能(ビット演算機能)があった。
FORTRAN IV
データ型宣言、条件文の追加、入出力命令の強化、倍精度複素数文字列などが追加/変更された。
この時のターゲットマシンはワードマシンであるため、整数値は2の35乗の範囲で定義されていた。また、実数の精度は2の27乗、倍精度実数の精度は2の54乗までであった。

言語仕様

Fortranの言語仕様は、年代によってかなり変化して来ている。他のプログラミング言語実装された構造化プログラミングの機能などがどんどん取り入れられて来ているからである。

FORTRAN 66

FORTRAN 66の言語仕様はおおよそ下記のとおり。

利用できる文字

  • 英数字
  • 特殊文字(空白、=、+、-、*、/、(、)、,、.、'、:、;、&、%、$、#、"、@)

プログラムの書式

プログラムは以下の形式で記述する。もともとパンチカードに書くことを前提としていたので、1行は80文字で構成されていた。行の左端からの文字位置を桁(けた)またはカラムと呼んだ。

1~5桁目
行番号を書く。1カラム目にCを書くとその行はコメント行になる。
6桁目
継続行であるときはここに任意の文字(空白又は0以外)を書く
7~72桁目
本文を書く
73~80桁目
シーケンシャル番号を書く(行を識別するための番号、本文には影響しない)

数など

以下のを扱える。

  • 整数(範囲は機種依存、4バイトであればその範囲)
  • 単精度実数(整数部+小数部、指数表示可能、精度は機種依存)
  • 倍精度実数(単精度の倍の精度を持つ)
  • 複素数(単精度または倍精度の実数の組み合わせ。2つの数字を()でくくる)
  • 論理型(.TRUE. 又は .FALSE.) ← .TRUE. と .FALSE. の両脇にドットがあることに注意!
  • 文字型(桁数のあとにHを記述し、その後に文字列を記述する。例えば 7HFORTRAN など)

変数など

以下の変数宣言を扱える。

  • 暗黙の宣言
    • 整数型(変数名の先頭がI~Nのもの)
    • 実数型(上記以外)
  • 明示的な型宣言
    • INTEGER宣言文
    • REAL宣言文
    • DOUBLE宣言文
    • COMPLEX宣言文
    • LOGICAL宣言文
  • 配列:宣言文のあとに()をつけ、要素数を記述する

  • 算術式(+、-、*、/、**(べき乗))
  • 比較(.LT.、.LE.、.GT.、.GE.、.EQ.、.NE.) ← 両脇にドットがあることに注意!
  • 論理演算(.OR.、.AND.、.NOT.) ← 両脇にドットがあることに注意!

実行
代入文
ASSIGN文
ASSIGN文で変数に割り当て、次の割当て型GO TO文で割り当てられた文番号にジャンプする
制御文
単純GO TO文
計算型GO TO文
飛び先がリストされていて、その後にある変数の内容を評価し、その値によって飛び先にジャンプする。
割当て型GO TO文
ASSIGN文で割り当てられた飛び先にジャンプする。
算術IF文
値を評価し、その値がマイナス0プラスによって3方向にジャンプする
論理IF文
CALL文
RETURN文
DO文
繰り返しを構成する。制御変数は整数型のみ
CONTINUE文
通常DO文の終了に使われる
STOP文
プログラムの終了
PAUSE文
プログラムを一旦中止し、コンソール上にメッセージを出す。記述できるメッセージは数字のみ
入出力
READ文
デバイスと書式を指定し、リストされた変数に値を入力する。デバイスは数字、5がカードリーダ入力、6がラインプリンタに定義されていることが多い。書式無しのREAD文もある
WRITE文
READ文の逆で、リストされた変数の内容を書式に従って出力する。
補助入出力文
磁気テープ装置の入出力を行ないやすくするために使われるのが基本。
REWIND文
読み出し又は書き込み位置を装置の先頭に位置づける。
BACKSPACE文
1つ前の記録位置に位置づける。
END FILE文
ファイルエンドマークを記録する。
宣言文
DIMENSION文
配列定義
COMMON文
プログラム間での共通領域を定義
EQUIVALENCE文
ある変数と別の変数を同じ物と見なす
EXTERNAL文
外部手続きであることを宣言
宣言文
型宣言文は配列定義も兼ねられる
INTEGER文
REAL文
DOUBLE PRECISION文
COMPLEX文
LOGICAL文
DATA文
初期データを定義する場合に利用する。
FORMAT文
各種の書式を定義する。
変換
I変換
整数の変換
F変換
小数点付きの実数の変換
E変換
指数表示の実数の変換
D変換
指数表示の倍精度実数の変換
G変換
桁数に応じて、EまたはF変換
L変換
論理型の変換
H変換
桁数指定の文字列の変換。プリンタに出力する場合、行の最初の桁が改行指示となる。
+
行送りなし(重ね打ち)
空白
1行送り(通常)
0
2行送り(1行飛ばし)
1
改ページ
A変換
文字列の変換
副プログラム関連
FUNCTION文
SUBROUTINE文
BLOCK DATA文

関数

以下の関数を扱える。

関数
そのプログラム内で有効な関数定義を1行で記述する。
組込み関数
組込み関数は、同じ機能でも引数と関数の型によって名前が異なる。関数名の先頭がI~Nのものが整数型、Dが倍精度実数型、Cが複素数型、それ以外が実数型である。
絶対値(IABS、ABS、DABS)
切捨て(INT、AINT、DINT)
剰余(MOD、AMOD)
最大値(MAX0、MAX1、AMAX0、AMAX1、DMAX1)
最小値(MIN0、MIN1、AMIN0、AMIN1、DMIN1)
実数化(FLOAT)
整数化(IFIX)
符号の付け替え(ISIGN、SIGN、DSIGN)
超過分(IDIM、DIM)
単精度実数化(SNGL)
倍精度実数化(DBLE)
複素数の実数部(REAL)
複素数の虚数部(AIMAG)
複素数化(CMPLX)
共役複素数(CONJG)
外部関数
あらかじめライブラリとして提供されている関数
関数副プログラム
関数副プログラムは、FUNCTION文で始まるサブルーチンである。
平方根(SQRT、DSQRT、CSQRT)
指数(EXP、DEXP、CEXP)
自然対数(ALOG、DLOG、CLOG)
常用対数(ALOG10、DLOG10)
正弦(SIN、DSIN、CSIN)
余弦(COS、DCOS、CCOS)
逆正接(ATAN、DATAN、ATAN2、DATAN2)
剰余(DMOD)
絶対値(CABS)

FORTRAN 77

FORTRAN 77は、FORTRAN 66に、よりプログラムを書きやすくするためのや、動作の明確化をはかっている。FORTRAN 66でのプログラムはほぼそのまま動くようになっている。以下はFORTRAN 77で追加/変更になった点の概要である。

数など

変数など

変数などについて以下の変更が加えられた。

  • IMPLICIT文で、暗黙の宣言の範囲を変更できるようになった。一部のコンパイラではすでに実装されていたものを仕様化したものである。整数実数だけではなく、文字型なども指定できる。
  • PARAMETER文で、定数に名前を与えられるようになった。FORTRAN 66では、定数は、直接式に書くか、変数を定数代わりに使う方法しかなかった。前者は定数の変更に手間がかかり、後者は定数を変更されてしまう危険性があった。
  • 配列の宣言に寸法宣言子を指定できるようになった。FORTRAN 66では配列は1から始まるだけであったが、FORTRAN 77ではマイナスの領域も定義できるようになった。たとえば以下のように定義できる。

DIMENSION ARRAY (-10:10)

  • 部分文字列が利用できるようになった。配列と同じような形で指定できる。

CHARACTER*4 CHR


{{{1}}}

  • 配列の初期化にDO形並びが利用できるようになった

  • の異なる変数/定数間での型の変換方法が定義された(?)
  • 文字の連結演算子(//)が定義された
  • 論理演算子に、等しければ真となる.EQV.と、異なれば真となる.NEQV.(XORと同じ)が定義された

  • 宣言
    • IMPLICIT文が追加された
    • (関数)副プログラムで、そのプログラム内で定義した変数を、そのプログラム内から抜け出たときも値が不定にならないように、保存するSAVE文が追加された
    • 主プログラム名を指定するPROGRAM文が追加された
  • 実行文
    • IF構造として、IF THEN~ と IF THEN~ELSE~END が利用できるようになった
  • 入出力
    • 入出力文の書式が大幅に強化された。以下のパラメータが利用できるようになった。これらを使うことで、入出力操作の柔軟性が向上した。
      • UNIT=(装置指定子)
      • FMT=(書式指定子)
      • ERR=(誤り指定子)
      • END=(ファイル終了指定子)
      • IOSTAT=(入出力状態指定子)
      • REC=(記録指定子)
    • 補助入出力文に以下の文が追加された
      • OPEN文
      • CLOSE文
      • INQUIRE文

関数

以下の関数が追加された

  • 文字長(LEN)
  • 部分列の位置(INDEX)
  • 正接(TAN、DTAN)
  • 逆正接(ASIN、DASIN)
  • 逆余弦(ACOS、DACOS)
  • 逆正接(ATAN、DATAN)
  • 双曲線正弦(SINH、DSINH)
  • 双曲線余弦(COSH、DCOSH)
  • 双曲線正接(TANH、DTANH)
  • 文字列の大小比較(LGE、LGT、LLE、LLT)

Fortran 90

Fortran 90には、他の言語にある、構造化記述を行なうための文法などが取り入れられた。

数など

  • 文字の種類として、英小文字、アンダースコアを始めいくつかの特殊文字が使えるようになった。
  • 定数変数の精度を指定する種別パラメータが追加された。また、精度を指定したり、精度情報を得るための関数が定義された。
  • 暗黙の宣言を無効にする、IMPLICIT NONE文が定義された。

変数など

変数などについて以下の変更が加えられた。

  • DIMENSION文やPARAMETER文などで、配列定数の定義の時に宣言を同時に行なえるようになった。
  • 構造体を定義するための、TYPE文が追加された。
  • 動的な配列や変数を定義するALLOCATABLEパラメータが、各定義文に利用できるようになった。また、実際に領域を割り当てるALLOCATE文と、割り当てた領域を開放するDEALLOCATE文が追加された。

  • ENDが拡張され、DO文などの終了文に利用できるようになった。
  • DOループを途中で飛ばすCYCLE文や途中で脱出するEXIT文が追加された。
  • 繰返し (ループ) を定義するDO WHILE文が追加された。
  • 多重分岐を行なうSELECT CASE~CASE~END SELECT文が追加された。
  • 仮引数の状態を指定するINTENT文が追加された。
  • ポインタ機能を実現するためのPOINTER文、NULLIFY文とTARGET文が追加された。
  • 数の比較をC言語と同様に記号で行なえるようになった。但し.NE.は /=と記述する。
  • 配列全体に対して操作が行なえるようになった。
  • 配列全体に対して比較条件を行なうWHERE文が追加された。
  • 内部副プログラムを定義するCONTAINS文が追加された。
  • 関数を再帰可能とするRECURSIVEパラメータをSUBROUTINE文、FUNCTION文の前に付けられるようになった。
  • モジュールを定義するための、MODULE文、USE文が追加された。
  • 利用者定義の操作を作成するためのINTERFACE文が追加された。
  • 名前並びを定義するNAMELIST文が追加された。
  • 他のソースファイルをマージするINCLUDE文が追加された。

仕様の変遷

JISにおける仕様は、以下のように変遷している。

初期 (FORTRAN 66)

1967年に、JISとして制定された。この時は、以下の3つの水準ごとに独立したJISが制定された。共通したタイトルは「電子計算機プログラム用言語 FORTRAN」であった。以下に水準間のおおよその違いを記す。

  • JIS C 6201(水準7000)
    • 複素数型と倍精度実数型がある
    • DATAと初期値設定副プログラム(BLOCK DATA文)がある
    • FORMAT文中の欄記述子にD,G,Aが定義できる
    • 変数配列手続き名は最大6文字
  • JIS C 6202(水準5000)
    • 変数、配列手続き名は最大6文字
  • JIS C 6203(水準3000)
    • 変数、配列、手続き名は最大5文字
    • 論理型のデータ、論理式、関係式、論理IF文は使えない。
    • 宣言文がない。
    • EXTERNAL文がない。
    • 3次元の配列がない。
    • 名前付きCOMMON文がない。
    • 文番号は4桁
    • COMMON文に配列宣言が使えない。
    • 整合配列がない。

なお、1971、1976年に若干の改訂がなされている。

FORTRAN 77時代

国際標準化機構 (ISO) は、米国規格協会 (ANSI) の X3J3 が作成した FORTRAN の規格 X3.9-1978 を ISO 1539-1980 として定めた。基本水準 (subset language) と上位水準 (full language) の2種類の水準からなっていた。これを基にして、同じく2水準の JIS C 6201-1982 が制定された。なお、1987年に、JISの分類が変更になり、この規格は JIS X 3001-1982 となった。内容には変更はない。

Fortran 90時代

FORTRAN 77を基に他の言語の特徴を組み込み、言語仕様を近代化しようとしたが、そのため仕様がなかなか決まらず、1991年に ISO/IEC 1539:1991として制定された。JISではそれを受け、制定された。

Fortran 95時代

いまでも基本は科学技術用行列演算用途であり、ベクトル型スーパーコンピュータは、Fortranを使ったプログラムで使用することが多い。Fortranは最近の言語Cのように、スタック等を使わず、コンパイル時に静的に記憶領域を確保するのが基本である。そのため、コンパイラはコードを最適化しやすいという利点がある。最近ではスタックや動的な記憶領域が使えるようになっている。

もともとのFORTRANは、字句解析の仕組みがCやJavaと大きく異なり、桁位置(行の左端からの文字位置)に依存していた。これを固定プログラム形式という。これは、当時、データの入力にパンチカードを使用していたためである。1桁目から5桁目が文番号で、6桁目が継続行の指定、7桁目から72桁目に文の本体を記述する。73桁目から80桁目は任意に指定可能な、行を識別するための文字列を記述する領域である。また、文字列定数中以外の空白文字は一切無視されていた(二つ以上の字句を空白無しで続けて書いたり、逆に一つの字句の途中に空白文字を入れても構わない)。

その後、Fortran 90時代には、現在のCのように、桁位置を気にすることない、自由プログラム形式 (文脈自由文法) で記述できるようになった(FORTRAN 77時代でも処理系によっては自由形式で記述できるものもあった)。予約語が存在しないという特徴は今でも残っている(同様に古くからあるCOBOLでは数百個の予約語があるのが一般的)。

Fortran 2003時代

主な新機能はCとの相互運用とオブジェクト指向である。

Fortran 2008時代

FORTRANと教育

教育向けコンパイラ

FORTRANは、情報処理分野で広く使われていたため、学校や会社の教育(情報処理技術者向け教育)で利用された。教育向けには、より詳細なエラー情報を出すための拡張がWaterloo大学でWATFOR(後にWATFIV)コンパイラとして実装された。この実装は日本の大学でも使われた。また2006年4月にはNAGから教育用FORTRAN統合開発環境Fortran Builderが発売された。 Fortran BuilderにはFortran言語が学習できる28回の授業コンテンツが標準搭載されている。

Fortranとスーパーコンピュータ

Fortranは科学技術計算用の言語なので、スーパーコンピュータでのプログラミング言語としてよく用いられる。したがって、スーパーコンピュータの高速演算機能を有効に使うための工夫がなされた。その1つの例としては、自動ベクトル化機能である。ベクトル型のスーパーコンピュータは、多くの演算を同時に行なうベクトル演算機能がハードウェアで提供されている。この機能を有効に使うために、FortranのDOループをベクトル演算装置で演算させるために、自動的にベクトル命令にする機能が提供された。また、DOループ内のベクトル演算に適さないものをDOループ外に追い出す機能などもある。たとえば、

      DO 100 I=1,N
        A(I) = B(I) * C(I)
  100 CONTINUE

のようなDO構文は、ほとんどの場合、1から数個のベクトル演算命令にコンパイルされる。そのほかにもDOループの中にIF文を含むような例、たとえば、

      DO 110 I=1,N
        IF (A(I) .LE. LIMIT) THEN
           B(I) = A(I) * Z
        END IF
  110 CONTINUE

のようなものもベクトル化できる場合がある。これは、いったんAの各要素がLIMIT以下かどうかを示すマスクベクトルを作成し、Aという配列(=ベクトル)に、変数Zをかけるとき、マスクベクトルを参照してベクトル演算を行なうことによって、DOループをベクトル化する。

このような作業は、すべてコンパイラが行ない、利用者にはできるだけ負担をかけないようにしている。しかし、より高度なベクトル化を行なうために、最適化を行なう支援ツールが用意されている場合もある。

FORTRANと日本語

コンピュータ上で日本語の文字を扱えるようになると、FORTRANでも日本語を扱う需要が出てきた。そのため、各社(メインフレームを作成していたメーカ)では、独自に言語仕様に日本語の文字を扱えるように拡張した。そのため、各社で日本語の扱い方が異なる事態になった。そこで、JEIDAでは1985年に、JEIDA-42で日本語FORTRANを策定した。

FORTRANで日本語を扱う場合、変数名等には日本語は使えず、文字列や日本語を扱うための専用の型(日本語型)、日本語を入出力するためのFORMAT文の要素の拡張が行なわれた。

参考文献

暗黙の型宣言による伝統的・慣習上の変数命名規則の誕生

FORTRANのプログラムにおいては、とくに宣言をしない場合、アルファベットI,J,K,L,M,Nのいずれかで始まる変数名で表される変数整数型(integer)になり、その他のアルファベット(A~H, O~Z)で始まるものは実数型(real)になる。これが「暗黙の型宣言」といわれるFORTRANの文法上の規則である。Iから始まる6文字に決まったのはIntegerの頭文字Iを連想しやすいからと思われる。

FORTRANのプログラムでは、特にループ構造を表すDO構文におけるカウンター変数としてアルファベットI~Nの1文字の変数名が伝統的によく使用されており、プログラミングにおける慣習上の変数命名規則の一つとなっている。FORTRANを参考にしたといわれるBASICにおいてもプログラミングにおける慣習上の変数命名規則が同様に存在し、ループ構造であるFOR~NEXT等には、アルファベットI~Nの1文字の変数名が伝統的に使用されている。さらに、Cその他のプログラミング言語のプログラミングにおいても伝統的にこれらの変数名が整数型の変数の変数名として使用されている。このようなプログラミングにおける変数命名規則の伝統・慣習は、FORTRANの暗黙の型宣言に由来している。なお、「変数の型はすべて明示的に宣言すべきであり暗黙の型宣言は不要である」とする見解もある。いずれにしても、半世紀以上の歴史のあるFORTRANは、一般的なプログラミングにおける変数命名規則の慣習に与えた影響も大きいといえよう。

Fortran 90以降ではIMPLICIT NONE文により暗黙の型宣言を無効にできるようになった。コンパイラのエラーメッセージや警告により暗黙の型宣言に起因するバグの発見が容易になるので積極的に用いるべきである。

構造化Fortran

FORTRAN 77までのFORTRANは、言語仕様が古いためにプログラムの構造化記述ができなかった。そこで、構造化記述を行なうために、プリプロセッサを使う方法が利用されていた。代表的なものとしては

がある。

FORTRANの記述の旧式さによる逸話

FORTRANで、コンマとピリオドを打ち間違えたらどうなるかの一例。

Cで、次のように書くプログラムの一部があったとする。

 int i;
 (中略)
 for( i=1; i<=5; i++ ) {
   何らかの処理;
 }

これをFORTRAN66で書くと次のように書ける。

      DO 10 I=1,5
      何らかの処理
  10  CONTINUE

最初の行は、整数型変数Iを1から5まで1ずつ増加させつつ、行ラベル10の行までを繰り返し実行することを表す。行ラベル10のCONTINUE文はループ制御の端末文ではなく、どこにでも置ける「何もしない」機能の文である。

ここで、DO文行のコンマをピリオドに打ち間違えたとする。すると、空白を無視するFORTRAN66では、この行は、

      DO10I=1.5

という、「DO10Iという実数型変数に1.5という実数を代入する代入文」と解釈される。FORTRANでは変数宣言が無い場合、DO10Iは実数型変数を暗黙に示すからである。 この結果、このプログラムは(他のどこからも参照されない)変数DO10Iへの代入とただ1回の「何らかの処理」が実行されるだけとなり、意図した繰り返し処理は 起こらない。

C言語などでは、空白文字は字句要素の切れ目として解釈されるため、DO と 10 と Iが結合して一つの字句要素になることはない。BASICにも、空白文字が字句要素の切れ目を表さないものがある。

上記と同様のバグによってNASAの宇宙ロケットが制御不能になり、爆破されたという逸話が度々語られる。しかしこれは二つの事故を混同し、さらに誇張されたものであることが、その後の調査により解っている。当事者達によるインターネット投稿を要約すると以下のとおり。

火星探査機マリナー1号はRate SystemおよびTrack Systemと呼ばれる二種類の制御系統を持っていた。Rate Systemは搭載型であり、地上型のTrack Systemは前者に対するバックアップとして動作する。1962年7月マリナー1号を打ち上げると、Rate Systemのハードウェアが故障したため、Track Systemで制御することになった。しかしTrack Systemはプログラム段階で、手書きの数式中のバー記号が見落とされており、微妙なタイミング差の平滑化処理に問題があった。その結果、制御コンピュータは、マリナー1号が正常に上昇しているにも関わらず、異常な補正動作をマリナー1号に指示し続けることとなった。大事をとった制御官はマリナー1号を爆破し、同機は大西洋へと沈んだ。

これとは別に、1963年マーキュリー宇宙船の軌道計算ソフトウェアを開発中に、スタッフの一人が計算精度に問題があることに気づいた。コードを調査した結果、「DO 10 I=1.10」という行を発見した。これを「DO 10 I=1,10」と修正したところ、期待した精度が得られるようになった。ただしこのバグによる誤差はほんの僅かであり、実際の宇宙飛行には全く問題ない程度であった。

規格

両者とも、次の3部からなる。

  1. 第1部:基底言語
  2. 第2部:可変長文字列
  3. 第3部:条件付き翻訳

主な処理系

FORTRANに関する参考資料