ニッシー
1990年生まれ
血液型 O型

こんにちは。ITブログアルケーナム管理人のニッシーです。

詳細プロフィールへ

お問い合わせへ






2018-11-05

CASL2で累乗を実現




今回は、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の場合(n0)に基数(底)がどんな値であれ必ず1になるので、その処理を行っています。



それでは、机上デバッグもどきでデータの流れを見てみます。


以下のデバッグは長いですが、興味のある方は見てみてください。


また、シミュレータをお持ちの方はそちらで動作を確認してみてください。



例1のPOW(8~18行)のトレース


初期状態

【汎用レジスタ】
GR0?
GR110
GR2101
GR3?

【フラグレジスタ】
ZFSFOF
000



8行 CPA GR1, =0

【汎用レジスタ】
GR0?
GR110
GR2101
GR3?

【フラグレジスタ】
ZFSFOF
000

CPA命令で、GR1の値 2 と 0 を比較します。
2 > 0 なのでフラグレジスタに変化はありません。



9行 JNZ NX

【フラグレジスタ】
ZFSFOF
000

ZFが0なので、JNZ命令で指定されたラベル「NX」に移動し12行を処理します。



12行 LD GR0, GR2

【汎用レジスタ】
GR0101
GR110
GR2101
GR3?

【フラグレジスタ】
ZFSFOF
000



13行 LAD GR1, -1, GR1

【汎用レジスタ】
GR0101
GR11
GR2101
GR3?

【フラグレジスタ】
ZFSFOF
000



14行 LAD GR2, -1, GR2

【汎用レジスタ】
GR0101
GR11
GR2100
GR3?

【フラグレジスタ】
ZFSFOF
000



~1ループ目~

15行 CALL MUL

CALL命令で、「MUL」サブルーチンを呼び出し、20行を処理します。





~MULサブルーチン内~

20行 LD GR3, GR0

【汎用レジスタ】
GR0101
GR11
GR2100
GR3101

【フラグレジスタ】
ZFSFOF
000



~1ループ目~

21行 ADDA GR0, GR2

【汎用レジスタ】
GR01001
GR11
GR2100
GR3101

【フラグレジスタ】
ZFSFOF
000

GR0の値が9になるため、フラグレジスタに変化はありません。



22行 SUBA GR3, =1

【汎用レジスタ】
GR01001
GR11
GR2100
GR3100

【フラグレジスタ】
ZFSFOF
000

GR3の値が4になるため、フラグレジスタに変化はありません。



23行 JPL LP2

【フラグレジスタ】
ZFSFOF
000

ZFが0、SFが0なので、JPL命令で指定されたラベル「LP2」に移動し21行を処理します。



~2ループ目~

21行 ADDA GR0, GR2

【汎用レジスタ】
GR01101
GR11
GR2100
GR3100

【フラグレジスタ】
ZFSFOF
000

GR0の値が13になるため、フラグレジスタに変化はありません。



22行 SUBA GR3, =1

【汎用レジスタ】
GR01101
GR11
GR2100
GR311

【フラグレジスタ】
ZFSFOF
000

GR3の値が3になるため、フラグレジスタに変化はありません。



23行 JPL LP2

【フラグレジスタ】
ZFSFOF
000

ZFが0 かつ SFが0 になり、JPL命令で指定されたラベル「LP2」に移動し21行を処理します。



~3ループ目~

21行 ADDA GR0, GR2

【汎用レジスタ】
GR010001
GR11
GR2100
GR311

【フラグレジスタ】
ZFSFOF
000

GR0の値が17になるため、フラグレジスタに変化はありません。



22行 SUBA GR3, =1

【汎用レジスタ】
GR010001
GR11
GR2100
GR310

【フラグレジスタ】
ZFSFOF
000

GR3の値が2になるため、フラグレジスタに変化はありません。



23行 JPL LP2

【フラグレジスタ】
ZFSFOF
000

ZFが0、SFが0なので、JPL命令で指定されたラベル「LP2」に移動し21行を処理します。



~4ループ目~

21行 ADDA GR0, GR2

【汎用レジスタ】
GR010101
GR11
GR2100
GR310

【フラグレジスタ】
ZFSFOF
000

GR0の値が21になるため、フラグレジスタに変化はありません。



22行 SUBA GR3, =1

【汎用レジスタ】
GR010101
GR11
GR2100
GR31

【フラグレジスタ】
ZFSFOF
000

GR3の値が1になるため、フラグレジスタに変化はありません。



23行 JPL LP2

【フラグレジスタ】
ZFSFOF
000

ZFが0、SFが0なので、JPL命令で指定されたラベル「LP2」に移動し21行を処理します。



~5ループ目~

21行 ADDA GR0, GR2

【汎用レジスタ】
GR011001
GR11
GR2100
GR31

【フラグレジスタ】
ZFSFOF
000

GR0の値が25になるため、フラグレジスタに変化はありません。



22行 SUBA GR3, =1

【汎用レジスタ】
GR011001
GR11
GR2100
GR30

【フラグレジスタ】
ZFSFOF
100

GR3の値が0になるため、フラグレジスタが変化します。



23行 JPL LP2

【フラグレジスタ】
ZFSFOF
100

ZFが1、SFが0なので、JPL命令で指定されたラベル「LP2」に移動せず24行を処理します。



24行 RET

RET命令で、「MUL」サブルーチンを抜けて、呼び出し元の「POW」サブルーチンに戻り16行を処理します。






16行 SUBA GR1, =1

【汎用レジスタ】
GR011001
GR10
GR2100
GR30

【フラグレジスタ】
ZFSFOF
100

GR1の値が0になるため、フラグレジスタが変化します。



17行 JPL LP1

【フラグレジスタ】
ZFSFOF
100

ZFが1なので、JPL命令で指定されたラベル「LP1」に移動せず18行を処理します。



18行 RET

RET命令で、「POW」サブルーチンを抜けて、呼び出し元の「MAIN」サブルーチンに戻り処理を終了します。



以上で処理が終了し、GR0が答えです。


GR0:(11001)2 = 25


52 = 25


52 は、25なので、正しい答えになっていますね。





累乗とは?



累乗とは、何回に渡って同じ数字を掛け合わせたのかを表すための表記です。



例えば、以下のような表現を用います。





このように表すことで、「2を100回掛け算したい」場合に、2 × 2 × 2...と長い掛け算の式を書かずに済み、整然と表記できるためです。



指数と底



本体の大きい方の数字を「底」、右上の小さい数字を「指数」と呼びます。






指数がゼロの場合



指数がゼロの場合、底がどんな数値であろうとも無条件で1になります。


例えば、


・20 = 1


・100 = 1


・1000 = 1


ただし、00 は、この限りではありません。


この限りではないというのは、便宜上...


・00 = 1


・00 = 0


の両方の場合があるためです。


本ブログでは便宜上、00 = 1 として扱うことにしています。


もうこの辺の定義については偉い数学者の方々に任せておきましょう。(笑)


アホの俺には分からん(^^);





最後に



累乗の計算は奥が深いですね~。


特に、0の0乗って本当に謎ですよね。


0の0乗で、ググると賢い方々が色々と解説してくださっているので、興味のある方は是非調べてみてください。


それでは、続きはまた次回にご期待を!









プロフィール

ニッシー
1990年生まれ
血液型 O型

こんにちは。ITブログアルケーナム管理人のニッシーです。

詳細プロフィールへ

お問い合わせへ