インターネット&PC120%活用:PC活用編

FORMAT文 (数値)

=============================================
今回はFortranの格調高きFormat文の数値の書式にについてまとめてみました。
最古のコンピュータ言語であるFORTRANは、紙にパンチされたデータを読み込む時代に
作られた言語であり、そんな時代の取り決めが化石のように残っています。このFORMAT文
というのも、そんな化石のにおいのするもののひとつですが、ちょっばかり古代の味をなめて
みましょう。
=============================================

1 はじめに
FORMAT文は、READ, WRITEなどの入出力文で、入出力の書式を指定する文です。BASICでも
print usingで画面出力やプリンター出力時の書式を制御したり、C言語でもprintf, scanfでは入出力
の書式を記述しましたが、それらと同様のものです。

実際のプログラムでは、FORMATは入出力命令のREADやWRITEと対になって使用されます。以下
のように、READ,WRITEの命令の中に参照するFORMAT文の文番号が記述されます。
WRITE(6,100)k
100   FORMAT('SUU=', I4)

今回はは数値の書式をまとめてみました。
文字の取り使いについては文字変数の取り扱い方を参照して下さい。

2 整数の欄記述子 I

(1) 整数の欄記述子の一般的規則
一般的にFORMAT文の( )中に記述する書式を指定する記述を、欄記述子と呼びます。
整数の欄記述子はIです。Iの後ろに欄の幅(ケタ数)を記述します。例えばI3とすると、正負の符号
も含めて3ケタ分が出力(または入力)されます。
複数の変数を入出力する時は、欄記述子をFORMAT文の中に複数記述します。例えば、3ケタ、
4ケタ、5ケタの3つの整数を出力する時は、
FORMAT(I3, I4, I5)
のように書きます。

出力の場合は、欄の幅が余れば左側に空白が挿入
され、欄の幅が足りなければ*が挿入されます(コンパイラにより、先頭だけ*にするものや、全部の
ケタに*を表示するものなど、仕様に違いがある)。

例えば、SalfordのFortran77では以下のようです。( _ は空白をあらわす)

欄記述子 出力
I5 123
_ _ 1 2 3
I5 -321
_ - 3 2 1
I3 1234
* * * *

欄記述子の前には、その欄記述子を繰り返し使用する回数を記述します。
例えば、3I5 と記述すると5ケタの整数の出力を3回繰り返す、ということになります。(これは、I5,I5,I5
と記述するのと同じことになります)

(2) 入力の時のFORMAT文の注意点
READ文で入力する時にもちょっと厄介なことがあり注意が必要です。あるコンパイラ(MicroSoftの
Fortarn80など)では、先頭(左側)の空白以外の空白はゼロとみなされます。ここがちょっと厄介な
ところです。
(SalfordのFortran77では、先頭以外の空白はリターンキー、あるいは区切り記号と同じにみなされ
るようです)
いずれにしても、コンパイラの仕様を確認しないと、ミスのおこりがちなところです。
入力者にうまく指示しないと、意図しない数値が入力されることになります。また指定した欄の幅
(ケタ数)より入力値が大きいと正しい値が入力されません。例えばI4という指定(符号をあわせて
4ケタ)に対して、-1234と入力すると、最初の4ケタだけが取り込まれて、-123という値が入力
されたことになります。
例えば、以下の通りのようになります。

欄記述子 入力欄(_は空白とする) 入力された値(Fortran80) 入力された値(Fortran77)
I4
_ 1 2 3
123 123
I6
_ _ 3 2 1 _
3210 321
I5
- 1 _ 2 _
-1020 -1
I4
- 1 2 3 4
-123 -123

なお、SalfordのFortran77ではREADの時は参照するFORMAT文を指定する必要はなく、
READ(5, *)
のように記述することができます。
FORMAT文を指定すると、入力データの形式が欄記述子の記述に厳密に制約されるので、
SalfordのFortran77のこの仕様はちょっと柔軟性があり便利です。


3 実数の欄記述子

(1) 実数の欄記述子
実数の欄記述子には、F,E,G の3つの型があります。

F型変換
F型変換は、rFw.dの形をとります。rは繰り返しの回数です。wは表示のケタ数を示し、dはそのうち
の小数部分のケタ数を示します。
例えば、F9.4とすると、全体のケタ数が9ケタ、うち小数部分が4ケタで表示されます。

<--- w --------->
<--d-->
5 5 . 3 1 7 5
1 2 3 4 . 7 5 0 0

F型変換の場合も出力欄の幅が余れば左側に空白が出力され、また小数部の欄が余れば0が
右側に出力されます。小数部の欄が不足すれば、不足した部分は表示されません(切捨てされた
のと同じ表示になる)。

欄記述子 数値 出力( _ は空白を示す)
F6.3 4.2
_ 4 . 2 0 0
F7.1 35.123
_ _ _ 3 5 . 3


E型変換
E型変換は、rEw.dの形をとります。rは繰り返しの回数です。wは全体の表示ケタ数、dは少数部分の
表示ケタ数を示します。表示は以下のようになるので、w>d+7 である必要があります。
(仮数1と指数部で7ケタ分の表示欄が必要)

<-----w---------->
仮数1 仮数2
<-d->
指数部
- _ . 2 5 6 E + 0 3

G型変換
G型は混合型と呼ばれる型で、データの絶対値の大きさによって、F型で表示したり、E型で表示したりします。
Gw.dの形をとり、wが表示の欄の幅を示し、dはそのうちの小数部分のケタ数を示します。
実際の表示は、出力しようとするデータの絶対値をnとすると、0.1=<n<10dの範囲ではF型として表示し、それ
以外ではE型として表示します。
F型で表示の部分は以下のようになります。

範囲 書式
0.1 =<n < 1.0 F(w-4).d
1.0 =<n< 10.0 F(w-4).(d-1)
... ...
10(d-2) =<n<10(d-1) F(w-4).1
10(d-1) =<n< 10d F(w-4).0

具体例を見ないと少しわかりにくいと思いますので、F,E,Gのそれぞれの型で同じ数字を表示した場合の
違いを実際のサンプルでみてみましょう。
C      FORMAT TEST
       INTEGER I,J
       REAL*4 A
       A=0.12345678E-05
       DO 1  I = 1,10,1
       J=I*10
       A=A*10.0
       WRITE(5,100) I, J,A, A, A
100    FORMAT(2I4, F20.8, E20.8, G20.8)
1      CONTINUE
       STOP
       END


以下は、上記のプログラムの実行例です。

D:\win95\ftn77#>frmtest
   1  10          0.00001235      0.12345678E-04      0.12345678E-04
   2  20          0.00012346      0.12345678E-03      0.12345678E-03
   3  30          0.00123457      0.12345677E-02      0.12345677E-02
   4  40          0.01234568      0.12345677E-01      0.12345677E-01
   5  50          0.12345678      0.12345678E+00      0.12345678
   6  60          1.23456776      0.12345678E+01       1.2345678
   7  70         12.34567738      0.12345677E+02       12.345677
   8  80        123.45677185      0.12345677E+03       123.45677
   9  90       1234.56774902      0.12345677E+04       1234.5677
  10 100      12345.67773438      0.12345678E+05       12345.678


(2) 実数の入力の注意点
実数の入力でも、注意すべきルールがあります。例えばF6.2と指定すると、符号、小数点含めて6ケタ、
小数点以下2ケタの指定になります。この時、例えば入力データが123.45のように、小数点を含んで
いれば、このとおり123.45として値がとりこまれます。しかし、入力データが12345のように小数点を
含んでいないと、欄記述子の記述のルールが適用されて、値は123.45として取り込まれてしまいます。
入力データが123.0なら、123.00として取り込まれます。
このように、実数の入力の場合は、以下のような規則に従います。
(A)入力データに小数点があれば、入力データのとおりに取り込む
(B)入力データに小数点がなければ、欄記述子に従って取り込む

整数の欄記述子のところでも書きましたが、SalfordのFortran77では、FORMAT文を指定しない
記述の仕方もできます。実数の入力も、いちいちFORMAT文の指定をしないほうが柔軟性があって
便利だと思います。

SalfordのFortran77で整数と実数の入力の時の動作を確認してみました。不正な値が入った場合の
処理などを確認してみて下さい。

サンプルプログラム pract1
I3(3ケタの整数)、F6.2(6ケタで、小数点以下2ケタの実数)を入力して、そのまま出力するプログラム
です。

C         program practice
          READ(5,100)j,x
100       FORMAT(I3,F6.2)
          WRITE(6,200)j,x
200       FORMAT('I ',I3, ' F ',F6.2)
          END

プログラムの実行例

D:\win95\ftn77#>pract1
1,1.0
I   1 F   1.00

D:\win95\ftn77#>pract1
12,12.34
I  12 F  12.34

D:\win95\ftn77#>pract1
12,123.45
I  12 F 123.45

D:\win95\ftn77#>pract1
1,1
I   1 F   0.01

D:\win95\ftn77#>pract1
12,12
I  12 F   0.12

D:\win95\ftn77#>pract1
123,123.45
I 123 F   0.00

D:\win95\ftn77#>pract1
12345,12.34
I 123 F   0.45

D:\win95\ftn77#>pract1
12,1234.56
I  12 F ******


問題ない場合



問題ない場合



問題ない場合



実数に小数点がないデータが入力された場合
欄記述子の書式が適用された。


実数に小数点がないデータが入力された場合
欄記述子の書式が適用された。


I3(符号含めて整数3ケタ)にオーバーした値が入力された
取り込まれた値は不正な値になっている。


I3(符号含めて整数3ケタ)にオーバーした値が入力された
取り込まれた値は不正な値になっている。


実数値にオーバーした値が入力された。

このようにREAD文での入力時に、FORMAT文を指定すると、入力データは欄記述子のとおりに
入力しないと、取り込まれた値が不正なものになります。FORTRANでデータを扱う時は、プログラム
設計時に入力データの書式をどうするかよく吟味し、また入力時にデータの書式を正しく守らせる
必要があります。

TopPage


inserted by FC2 system