next up previous contents index
: デバッガ : Risa/Asir 入門 : Risa/Asir 入門   目次   索引

Risa/Asir で書く短いプログラム

本書のもととなった講義では, 高校数学の教科書で紹介されている BASIC のプログラミング をひととおり勉強したあと, この本の内容にはいっていくことも多かった. BASIC はいろいろ批判もあるが, (1) 行番号, (2) 代入文や命令文, (3) goto 文, をもち, マシン語を勉強しなくても ``計算機とはなにか''というイメージをある 程度持つための訓練には最適の言語の一つであろう. Risa/Asir のユーザ言語は, C に似た文法をもつより抽象化された言語で あるが, それが実際の計算機でどのように実行されるのか 常に想像しながら使用するのと, そうでないのとは, 大きな違いがある. 達人への道を歩もうという人は, 抽象化された 言語で書かれていようが, 実際の計算機でどのように実行されるのか をわかっていないといけない. プログラム実行中のメモリ使用の様子を手にとるように 描写できるようになれば, 計算機の達人への道は間違いなしである. 前節で計算機の仕組みの概略と 2進数について説明したのは つねにこの ``プログラム実行中のメモリ使用の様子を手にとるように 描写できるように'' ということを念頭において計算機のプログラミングをしてほしい からである.

訳のわからない説教で始めてしまったが, この意味はだんだんと 分かるであろう. とにかく Risa/Asir で短いプログラムを書いてみよう.

くりかえしは以下のように for 文を用いる.

例題 4.1   [02]     

for (K=1; K<=5; K=K+1) { print(K); };

を実行してみなさい. このプログラムはprint(K)K の値を1から5まで変えながら5回実行する.

入出力例 4.1       

[347]  for (K=1; K<=5; K=K+1) { print(K); };
1
2
3
4
5
[348] 0
[349]

例題 4.2   [02]      $1$ から $100$ までの数の和を求めるプログラム

      S = 0;
      for (K=1; K<=100; K++) {
         S = S+K;
      }
      print(S);

または

   def main() {
     S = 0;
     for (K=1; K<=100; K++) {
         S = S+K;
     }
     print(S);
   }
   main();

を実行してみなさい. これらの内容を書いてあるファイル a.rr を作成して, load("./a.rr"); でロード実行してもよい (unix の場合). Windows の場合は, プログラムをファイルから読み込むには ``ファイル $\rightarrow$ 開く'' を用いる.

同じプログラムを BASIC で書くと以下のようになる.

10 S = 0
20 for K=1 to 100
30   S = S+K
40 next K
50 print S

条件分岐をするときには if 文を用いる. 次の例は, $b$, $c$ に数をセットすると2 次方程式 $ x^2 + b x + c = 0 $ の解の近似値を求める. なお @i は虚数単位 $\sqrt{-1}$ である.

B = 1.0; C=3.0;
D = B^2-4*C;
if (D >= 0) {
   DQ = deval(D^(1/2));
   print([ -B/2+DQ/2, -B/2-DQ/2]);
}else {
   DQ = deval((-D)^(1/2));
   print([ -B/2+@i*DQ/2, -B/2-@i*DQ/2]);
}

条件分岐をするためにもちいる表現をまとめておく.
記号 意味
== ひとしいか? X == 1 ( ${\tt X}=1$ か?)
!= ひとしくないか? X != 1 ( ${\tt X}\not=1$ か?)
! でない(否定) !(X==1) ( ${\tt X}\not=1$ か?)
&& かつ (X < 1) && (X > -2) ( ${\tt X} < 1 かつ {\tt X} > -2$ か?)
|| または (X > 1) || (X < -2) ( ${\tt X} > 1 または {\tt X} < -2$ か?)
念のために, ``かつ'' と ``または'' の定義を復習しておく. 次の表では, T で 真 (True) を, F で 偽 (False) を表す.
A B A && B
T T T
T F F
F T F
F F F
    
A B A || B
T T T
T F T
F T T
F F F
なお Asir では 偽を 0, 真を 0 でない数で表現してよいし, 偽を false, 真を true と書いてもよい. たとえば,

if (1) {
   print("hello");
}else{
   print("bye");
}

hello を出力する.

条件判断をかっこでくくって合成してもよい. たとえば

(1 || 0) && 1
は 1 すなわち真 (T) となる.

問題 4.1        次のプログラムで hello は何回表示されるか?

for (I=0; I<10; I++) {
   if (((I^2-6) > 0) && ( (I < 3) || ( I > 6))) {
      print("hello");
   }
}

例題 4.3   1 から 20 までの自然数 $N$ についてその $2$ 乗の逆数 $\frac{1}{N^2}$ の和を求めるプログラムを書き, 実際に計算機でどのように実行されているのか メモリと CPU の様子を中心として説明しなさい. メモリと CPU については, 第 3.1 節を見よ.
プログラムは以下のとおり. 参考のため BASIC のプログラムも掲載, 解説する.
Asir 版

S=0;
for (N=1; N<=20; N++) {
  S = S+1/(N*N);
}
print(S);

BASIC 版

10 S = 0
20 for N=1 to 20 
30   S = S+1/(N*N)
40 next N
50 print N


Asir は 17299975731542641/10838475198270720 なる答えを戻す. これを, 小数による近似値になおすには たとえば函数 deval(S) (S の64bit 浮動小数点数への変換) または eval(S*exp(0)) (S の任意精度浮動小数点数への変換)を用いる. 一方 BASIC (たとえば 16bit 版 UBASIC) は 1.5961632439130233163 を戻す. この違いは Asir は分数ですべてを計算しているのに 対して, basic では 1/(N*N) を近似小数になおして 計算していることによる.
``実際に計算機でどのように実行されているのか メモリと CPU の様子を中心として説明'' するときに大事なポイントは以下の とおり.
  1. プログラムもメモリに格納されており, それを CPU が順に読み出して 実行している. 注意: この場合は正確にいえばインタプリタがその作業をしている. インタプリタは プログラムを順に読みだし, CPU が実行可能な形式に変換して実行している. (初心者にはこの違いはすこしむづかしいかも.)
  2. SN という名前のついたメモリの領域が確保され, その内容がプログラムの実行にともない時々刻々と変化している.
    図 4.1: メモリの図解
    \begin{figure}\par
\begin{center}
\begin{tabular}{\vert c\vert c\vert}
\hline
場...
...\ \hline
& \\ \hline
& \\ \hline
& \\
\end{tabular}\end{center}
\end{figure}
説明: 文 S=0 の実行で, メモリの S という名前のついた領域に 数 $0$ (ゼロ) が格納される. (図 4.1 を見よ.)
for 文 の始めで, メモリの N という名前のついた領域に 数 $1$ が格納される.
S = S+1/(N*N) では 1/(N*N) が CPU で計算されてその結果と S の現在の値 $0$ が CPU で加算されメモリ S に格納され S の値は更新される.
以下, 省略.


next up previous contents index
: デバッガ : Risa/Asir 入門 : Risa/Asir 入門   目次   索引
Nobuki Takayama 平成15年9月12日