Fortran プログラミング (その2)


今日の内容

今日は Fortran プログラミング演習の2回目です。今日は、データの型、繰り返し(ループ)処理について勉強します。

Fortran は教科書には記載されていません。練習問題のサンプルプログラムとその解説が教科書代わりです。これらを熟読すれば提出課題はできます。必ずよく読んで実行し、理解するようにしなさい。また以下のサイトが参考になるので、必要に応じて参照しなさい。


今日の演習

プログラムで用いるすべての変数は、それがどの種類のデータを表すのかによって「型」をもっており、一般にどの型として使用するのかプログラムのはじめであらかじめ宣言しておく必要がある。
また、数値データは型によって処理に違いがあるので、これも十分理解しておく必要がある。
演算を行う際、実数(型データ)は有限長さの2進数で内部表現されるため、一般に必ず誤差をともなうことも理解しておく必要がある。

1.実数型、整数型の表現方法
実数型の整数を表すときは、2.0 や2. など小数点をつけて表現する。整数型の表現は、2 など小数点をつけない。

2.異なる型の混合演算および代入
データの型が異なる場合の演算や代入は、以下の約束が適用される。
■演算
異なる型の数値データ間の演算では、実数の整数乗を除いて、より強い方の型に変換して型をそろえてから演算が行われる。
(型の強さ:実数>整数,倍精度>単精度)
■代入
代入文の右辺と左辺で型が異なる場合は、右辺を評価後、代入先の型に変換して代入が行われる。

数値データの変換規則(一例)
 整数型→実数型:小数点をつける。
 実数型→整数型:切り捨て整数化。


これらを踏まえて、下記の結果を予測しなさい。
i: 実数型,r: 実数型として、
1/2     =
1.0/2   = 
1/2.0   =
1.0/2.0 =

r=1/2   => r=
r=1.0/2 => r=
i=1.0/2 => i=
r=-5.0/3 => r=
r=-5/3   => r=
i=-5/3   => i=

2**2     =
2.0**2   =

4**0.5     =
4.0**0.5   =
4.0**(1/2) =
SQRT(4.0)  =
結果は自分で確かめて下さい。
Fortran プログラムの入力と実行の仕方は先週の課題の説明を参照すること。
123456789....
+-----+--------------------------------------
C     calculation of integer and real number
C
      IMPLICIT NONE
      INTEGER :: i=0
      REAL :: r=0.0
C
      WRITE(*,*) 'integer :', i
      WRITE(*,*) 'real    :', r
C
      WRITE(*,*) '1/2     = ', 1/2
      WRITE(*,*) '1.0/2   = ', 1.0/2
      WRITE(*,*) '1/2.0   = ', 1/2.0
      WRITE(*,*) '1.0/2.0 = ', 1.0/2.0
C
      r=1/2
      WRITE(*,*) 'r=1/2   => ', r
      r=1.0/2
      WRITE(*,*) 'r=1.0/2 => ', r
      i=1.0/2
      WRITE(*,*) 'i=1.0/2 => ', i
      r=-5.0/3
      WRITE(*,*) 'r=-5.0/3 =>', r
      r=-5/3
      WRITE(*,*) 'r=-5/3   => ', r
      i=-5/3
      WRITE(*,*) 'i=-5/3   => ', i
C
      WRITE(*,*) '2**2     = ', 2**2
      WRITE(*,*) '2.0**2   = ', 2.0**2
C
      WRITE(*,*) '4**0.5     = ', 4**0.5
      WRITE(*,*) '4.0**0.5   = ', 4.0**0.5
      WRITE(*,*) '4.0**(1/2) = ', 4.0**(1/2)
      WRITE(*,*) 'SQRT(4.0)  = ', SQRT(4.0)
C
      STOP
      END

練習問題 1

1 から n ( =100 とする) までの整数の和を求める以下のサンプルプログラムを入力し、実行させなさい。

01から13までの行番号がついている行が入力するプログラム(ソースコード)である。 行番号および桁目盛は説明と見やすさを考慮してつけているので入力する必要はない。枠線で囲まれている部分の中だけを入力すること。

プログラムの説明

   1: 1桁目が C で始まる行はコメント行であり、実行されない。
   3: 暗黙の型宣言を無効にする。
   4: 整数型 (INTEGER) である3つの変数 i, n, t を宣言する。
      変数n(繰り返し数)については、初期値を代入する。

   6: 合計 t の初期値を 0 にする(繰り返し処理の直前にするのが望ましい。)。

   7: 今日のポイント:DO ループ (繰り返し処理)

      DO ループ処理の文法(約束ごと)は、
      
        DO 制御変数=初期値, 終値, [増分]
         実行文 (通常は制御変数を何らかの形で使う。)
        END DO
      
      初期値、終値、増分は整数(型)を使う。
      初期値、終値、増分は変数であってもよい。
      増分=1 の時は省略することができる。
      増分は負でもよいが、この場合 初期値 > 終値でなければ、実行されない。

      # (次の行から)END DO 文までを、制御変数(i)の値を 1 から 
      # (増分1ずつ増やして)終値(n)になるまで(を超えるまで)実行せよ。
      という命令である。

   8: t+i の 値を t に代入する(t が i だけ増えるから足していくことになる)。
      = は代入であって等式でないことに注意。

   9: DO ループの終わりを示す。
 
  10: 結果の表示 (WRITE)。
  12: 処理を終了する (STOP)。
  13: プログラムの終わりを示す (END)。
Fortran プログラムの入力と実行の仕方は先週の課題の説明を参照すること。

練習問題 2

区間 (a, b) を n等分して各分点 x0=a, x1=a+h, x2=a+2h,......,xn=a+nh=b での関数 f(x) の値を計算する場合を考える。
f(x)=SQRT(4.0-x**2)(SQRT( )は平方根を表す関数), 区間(0,2), n=16 として、以下のサンプルプログラムを入力し、実行させなさい。

01から16までの行番号がついている行が入力するプログラム(ソースコード)である。 行番号および桁目盛は説明と見やすさを考慮してつけているので入力する必要はない。枠線で囲まれている部分の中だけを入力すること。

プログラムの説明

    1: 1桁目が C で始まる行はコメント行であり、実行されない。
    3: 暗黙の型宣言を無効にする。
  4,5: 実数型変数 a, b, h, x, y 、整数型変数 i, n を宣言する。
       変数a, b, n については、初期値を代入する。

    7: 分点間の距離(きざみ幅)h を求める。
       REAL(n) で、n を実数型に変換して使用。

    9: 今日のポイント:DO ループ。

       # (次の行から)END DO 文までを、変数 i の値を 0 から(1 ずつ増やして) 
       # n になるまで実行せよ。

   10: x の計算 ループを繰り返すたびに h ずつ大きくなる。

       「参考:演算子の計算の順位」
       かっこ( )でくくられていない場合、『累乗>積・商>和・差』の順に計算が進められる。
       同順位のものは、累乗は右から、それ以外は左から計算が進められる。

   11: y の計算。
   12: 計算結果の出力 (WRITE)。
   13: DO ループの終わりを示す。

   15: 処理を終了する (STOP)。
   16: プログラムの終わりを示す (END)。
Fortran プログラムの入力と実行の仕方は 先週の課題の説明を参照すること。

今日の提出課題

練習問題 1,2 を踏まえて以下のプログラムを作成せよ。(問題文は自分で作成して下さい。)
プログラム(ソースファイル)と実行結果をまとめて印刷して提出しなさい。

\documentclass[a4j]{jarticle}
%
\setlength{\topmargin}{-2cm}
\setlength{\textheight}{25cm}
\setlength{\textwidth}{10.8cm}
\setlength{\oddsidemargin}{4cm}
\setlength{\evensidemargin}{4cm}
\title{Report of Fortran programming on second class}
\author{written by Class Staff}
\date{\today}
%
\begin{document}
\maketitle
%
関数
\( f(x) \)
の区間
\( (a, b) \)
を$n$等分する各分点を
\( x_0=a, x_1=a+h, x_2=a+2h, \cdots \cdots, x_n=a+nh=b \)
とするとき,次の式を用いて近似的に積分値を求めることができる.\\
\[
S \approx h \sum_{i=0}^{n-1} f(x_i)
\]
ここで,$h$は分点間の距離(きざみ幅)である.

\( f(x)=\sqrt{4-x^2} \)
,区間
\( (0,2) \)
,$n=2,4,8,16,32,64,128,256$として,積分値
\( \int_0^2 \sqrt{4-x^2}dx \)
の近似値を求めるプログラムを作成し,実行させなさい.
また,この積分値の真値は容易に求められるので,真値とのずれの変化を調べなさい.

ただし,$n$はプログラム中の変数の値を手動で1回1回換えて計算するのではなく,
プログラムで一気に計算させて表のような形式で出力するプログラムにすること.
(もちろん,DO ループを使って下さい.)
\end{document}

プリンタ出力の提出をもって出席とします。したがって、途中までしかできていない場合でも、プリンタに出力して提出しなさい。出力できない者は口頭で申し出ること。その場合、来週の演習時間までに完成させて演習開始時に提出すること。


おまけ

課題が終わってしまって時間に余裕がある人は、トライしよう。 提出する際は1行目に氏名、学生番号を書いて課題とは別紙にしなさい。

(問題)インターネットで電子メールを使っていると、「幸福の手紙」「不幸の手紙」「ネズミ講」のようなメールをもらうことがあります。よくある例としては、
  1. 「このメールを○人に送らないと不幸になります。」
  2. 「新しい金儲けのビッグチャンスです。今すぐこのメールを友人に転送して下さい。」
  3. 「○○国で不治の病におかされている○○少年を励ますために、このメールの輪を広げて下さい。」
  4. 「新しいウイルスが発見されました。すぐに友人に知らせてあげて下さい」
この手のメールはまず100%、悪戯かデマもしくは違法です。 このようなメールを受け取っても絶対にメールを広めないこと。メールの内容・趣旨を問わず(たとえそれが良心からであっても)、このような行為(チェーン・メールという)は禁じられています。

さて、ある人が次のようなメールを出しました。

「このメールを受け取った人は、5人の友人にメールを転送して下さい。」

このメールを受け取った人は皆忠実に指示に従い、同じ人が2度メールを受け取らないとします。メールの転送を行うたびにメールの数がいくつに増えるか、転送の回数15回まで計算しなさい。

メールの数を整数で表した場合と、実数で表した場合の計算結果を比較しなさい。

メールを受け取った人の数が日本の人口(1億3千万人とする)、地球の人口(62億人とする)を越えるには、何段階の転送が行われる必要があるか?

(問題) 以下の出力を得るプログラムを DO ループを用いて作成せよ。出力結果が正しければ空白の有無の差異はとくに問わない。(Xは大文字のエックスでよい。)
   1 X  1 =  1
   1 X  2 =  2
   1 X  3 =  3
   1 X  4 =  4
   1 X  5 =  5
   1 X  6 =  6
   1 X  7 =  7
   1 X  8 =  8
   1 X  9 =  9
   2 X  2 =  4
   2 X  3 =  6
   2 X  4 =  8
   2 X  5 =  10
   2 X  6 =  12
   2 X  7 =  14
   2 X  8 =  16
   2 X  9 =  18
   3 X  3 =  9
   3 X  4 =  12
   3 X  5 =  15
   3 X  6 =  18
   3 X  7 =  21
   3 X  8 =  24
   3 X  9 =  27
   4 X  4 =  16
   4 X  5 =  20
   4 X  6 =  24
   4 X  7 =  28
   4 X  8 =  32
   4 X  9 =  36
   5 X  5 =  25
   5 X  6 =  30
   5 X  7 =  35
   5 X  8 =  40
   5 X  9 =  45
   6 X  6 =  36
   6 X  7 =  42
   6 X  8 =  48
   6 X  9 =  54
   7 X  7 =  49
   7 X  8 =  56
   7 X  9 =  63
   8 X  8 =  64
   8 X  9 =  72
   9 X  9 =  81

戻る