今回は、CASL2を使った「累乗」について見てみたいと思います。
ループ処理を用いた累乗
例1:52 の計算
1 | MAIN | START |
|
2 | | LD GR1, IDX |
|
3 | | LD GR2, BAS |
|
4 | | CALL POW |
|
5 | | ST GR0, ANS | ;答えをANS番地に格納
|
6 | | RET |
|
7 | | |
|
8 | POW | CPA GR1, =0 | ;指数と0を比較
|
9 | | JNZ NX | ;指数が0でないならNXに移動
|
10 | | LAD GR0, 1 | ;GR0に1を転送
|
11 | | RET |
|
12 | NX | LD GR0, GR2 | ;底をGR0に転送
|
13 | | LAD GR1, -1, GR1 | ;指数をデクリメント
|
14 | | LAD GR2, -1, GR2 | ;底をデクリメント
|
15 | LP1 | CALL MUL | ;MULサブルーチンの行に移動
|
16 | | SUBA GR1, =1 | ;指数をデクリメント
|
17 | | JPL LP1 | ;指数が0より大きいならLP1に移動
|
18 | | RET |
|
19 | | |
|
20 | MUL | LD GR3, GR0 | ;底を編集用にGR3に転送
|
21 | LP2 | ADDA GR0, GR2 | ;底に底を加算
|
22 | | SUBA GR3, =1 | ;底から -1
|
23 | | JPL LP2 | ;底が0より大きいならLP2に移動
|
24 | | RET |
|
25 | | |
|
26 | IDX | DC 2 | ;指数
|
27 | BAS | DC 5 | ;底
|
28 | ANS | DS 1 | ;答え
|
29 | | END |
|
シミュレータにそのままコピー&ペーストで使えます。
解説
このループを用いた累乗は、単純に
指数で示される値分掛け算を繰り返すことで実現しています。
掛け算自体は、「ループ処理を用いた乗算」を用いています。
プログラム上で、
赤字で示される
8~11行のコードは、指数が0の場合(n
0)に基数(底)がどんな値であれ必ず1になるので、その処理を行っています。
それでは、机上デバッグもどきでデータの流れを見てみます。
以下のデバッグは長いですが、興味のある方は見てみてください。
また、シミュレータをお持ちの方はそちらで動作を確認してみてください。
例1のPOW(8~18行)のトレース
初期状態
【汎用レジスタ】
【フラグレジスタ】
8行 CPA GR1, =0
【汎用レジスタ】
【フラグレジスタ】
CPA命令で、GR1の値 2 と 0 を比較します。
2 > 0 なのでフラグレジスタに変化はありません。
9行 JNZ NX
【フラグレジスタ】
ZFが0なので、JNZ命令で指定されたラベル「NX」に移動し12行を処理します。
12行 LD GR0, GR2
【汎用レジスタ】
【フラグレジスタ】
13行 LAD GR1, -1, GR1
【汎用レジスタ】
【フラグレジスタ】
14行 LAD GR2, -1, GR2
【汎用レジスタ】
【フラグレジスタ】
~1ループ目~
15行 CALL MUL
CALL命令で、「MUL」サブルーチンを呼び出し、20行を処理します。
~MULサブルーチン内~
20行 LD GR3, GR0
【汎用レジスタ】
【フラグレジスタ】
~1ループ目~
21行 ADDA GR0, GR2
【汎用レジスタ】
【フラグレジスタ】
GR0の値が
9になるため、フラグレジスタに変化はありません。
22行 SUBA GR3, =1
【汎用レジスタ】
【フラグレジスタ】
GR3の値が
4になるため、フラグレジスタに変化はありません。
23行 JPL LP2
【フラグレジスタ】
ZFが
0、SFが
0なので、JPL命令で指定されたラベル「LP2」に移動し21行を処理します。
~2ループ目~
21行 ADDA GR0, GR2
【汎用レジスタ】
【フラグレジスタ】
GR0の値が
13になるため、フラグレジスタに変化はありません。
22行 SUBA GR3, =1
【汎用レジスタ】
【フラグレジスタ】
GR3の値が
3になるため、フラグレジスタに変化はありません。
23行 JPL LP2
【フラグレジスタ】
ZFが
0 かつ SFが
0 になり、JPL命令で指定されたラベル「LP2」に移動し21行を処理します。
~3ループ目~
21行 ADDA GR0, GR2
【汎用レジスタ】
【フラグレジスタ】
GR0の値が
17になるため、フラグレジスタに変化はありません。
22行 SUBA GR3, =1
【汎用レジスタ】
【フラグレジスタ】
GR3の値が
2になるため、フラグレジスタに変化はありません。
23行 JPL LP2
【フラグレジスタ】
ZFが
0、SFが
0なので、JPL命令で指定されたラベル「LP2」に移動し21行を処理します。
~4ループ目~
21行 ADDA GR0, GR2
【汎用レジスタ】
【フラグレジスタ】
GR0の値が
21になるため、フラグレジスタに変化はありません。
22行 SUBA GR3, =1
【汎用レジスタ】
【フラグレジスタ】
GR3の値が
1になるため、フラグレジスタに変化はありません。
23行 JPL LP2
【フラグレジスタ】
ZFが
0、SFが
0なので、JPL命令で指定されたラベル「LP2」に移動し21行を処理します。
~5ループ目~
21行 ADDA GR0, GR2
【汎用レジスタ】
【フラグレジスタ】
GR0の値が
25になるため、フラグレジスタに変化はありません。
22行 SUBA GR3, =1
【汎用レジスタ】
【フラグレジスタ】
GR3の値が
0になるため、フラグレジスタが変化します。
23行 JPL LP2
【フラグレジスタ】
ZFが
1、SFが
0なので、JPL命令で指定されたラベル「LP2」に移動せず24行を処理します。
24行 RET
RET命令で、「MUL」サブルーチンを抜けて、呼び出し元の「POW」サブルーチンに戻り16行を処理します。
16行 SUBA GR1, =1
【汎用レジスタ】
【フラグレジスタ】
GR1の値が0になるため、フラグレジスタが変化します。
17行 JPL LP1
【フラグレジスタ】
ZFが1なので、JPL命令で指定されたラベル「LP1」に移動せず18行を処理します。
18行 RET
RET命令で、「POW」サブルーチンを抜けて、呼び出し元の「MAIN」サブルーチンに戻り処理を終了します。
以上で処理が終了し、GR0が答えです。
GR0:(11001)2 = 25
52 = 25
5
2 は、25なので、正しい答えになっていますね。
累乗とは?
累乗とは、
何回に渡って同じ数字を掛け合わせたのかを表すための表記です。
例えば、以下のような表現を用います。
このように表すことで、
「2を100回掛け算したい」場合に、
2 × 2 × 2...と長い掛け算の式を書かずに済み、整然と表記できるためです。
指数と底
本体の大きい方の数字を
「底」、右上の小さい数字を
「指数」と呼びます。
指数がゼロの場合
指数がゼロの場合、
底がどんな数値であろうとも無条件で1になります。
例えば、
・20 = 1
・100 = 1
・1000 = 1
ただし、
00 は、この限りではありません。
この限りではないというのは、便宜上...
・00 = 1
・00 = 0
の両方の場合があるためです。
本ブログでは便宜上、
00 = 1 として扱うことにしています。
もうこの辺の定義については偉い数学者の方々に任せておきましょう。(笑)
アホの俺には分からん(^^);
最後に
累乗の計算は奥が深いですね~。
特に、0の0乗って本当に謎ですよね。
0の0乗で、ググると賢い方々が色々と解説してくださっているので、興味のある方は是非調べてみてください。
それでは、続きはまた次回にご期待を!