標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第547回]

●累乗その2

前回お伝えしましたように、ND80ZVのプリント基板が出来てきてしまいましたので、ND80ZV組立キットの、組立説明書の作成作業にとりかかりました。
なかなかに大変な作業です。
組立説明書だけではなくて、そのほかもろもろの説明書も仕上げていかなくてはなりません。
そういう状況のなかで、本連載も続けていくとなりますと、そりゃあもう大変で気ばかりあせってしまいます。

ただでさえもどかしい説明がもっともどかしいことになってしまうかもしれません。なにぶんご容赦を願います。
説明書の作成作業も進んでまいりましたならば、ときどきはそちらの状況についてもご報告申し上げるつもりでおりますが、ここしばらくは、いままでのお話の流れといたしまして、Z80BASICをテーマにして続けていきたいと思います。

前々回はZ80BASICの累乗について説明をいたしました。
今回もそのサンプルということで、累乗についてのご紹介です。

こんなプログラムを書いてみました。

>list
    10 FOR X=2 TO 10
    20 Y=X^X
    30 PRINT X,Y,Y^(1/X)
    40 NEXT X
>run
2            4            2
3            27           3
4            256          4
5            3125         5
6            46655.9      6
7            823541       6.99999
8            0.167772E+8  8
9            0.38742E+9   8.99999
10           0.999997E+10 9.99999
なにをやっているかわかりますでしょうか?
X=2〜9について、まずXのX乗を求めて、それをYに入れます。 次にそのYの1/X乗を求めます。
X乗したものをまた1/X乗するわけですから、もとの数に戻るはずです。
Yは値が急速に大きくなりますから、通常の数値の表現では桁数が大きくなってしまいますから、指数表示になります。
大きな数は末尾まで計算できなくなりますから、計算誤差が生じます。
でも、しっかり計算してますでしょう。

今度は倍精度で計算してみます。
>list
    10 FOR X#=2 TO 10
    20 Y#=X#^X#
    30 PRINT X#,Y#,Y#^(1/X#)
    40 NEXT X#
>run
2            4            2
3            27           3
4            256.0000000000001         4
5            3125.000000000001         5
6            46655.99999999999         5.999999999999999
7            823543.0000000005         7
8            16777216.00000001         8
9            387420488.9999999         8.999999999999999
10           10000000000.00001         10

倍精度でも誤差が生じることには違いはありません。
実用上は問題の無い範囲の誤差なのですが、見た目に気持ちが悪い、という場合には、奥の手を使います。

>    30 PRINT X#,FIX(Y#+0.001),FIX(Y#^(1/X#)+0.001)
>run
2            4            2
3            27           3
4            256          4
5            3125         5
6            46656        6
7            823543       7
8            16777216     8
9            387420489    9
10           10000000000  10

ちょいと一部を直しただけで、ご覧の通り、見事にきれいになってしまいました。
何をやったかおわかりになりますでしょうか?
FIX()は整数化を行う関数です。
Z80BASICでの整数は2バイト16ビットの数しか扱えませんが、FIX()で整数化した値は、それよりも大きな整数を扱うことができます。
見かけ上、誤差をなくするために、もとの数に小さな数を加算した上で整数化します。
こうすることで、値が切り上がって、きれいな整数値になります。

最初の実数値での計算についても、FIX()を使ってみました。

>list
    10 FOR X=2 TO 10
    20 Y=X^X
    30 PRINT X,FIX(Y+0.001),FIX(Y^(1/X)+0.001)
    40 NEXT X
>run
2            4            2
3            27           3
4            256          4
5            3125         5
6            46655        6
7            823541       7
8            0.167772E+8  8
9            0.38742E+9   9
10           0.999997E+10 10

こちらも結果の値はきれいに端数が取れて元通りの数値になりましたが、累乗の値はきれいになりません。
これは24ビットで正確に計算できる数の範囲を超えているためにどうしようもないのです。
こういうところでは、倍精度演算が真価を発揮します。

しつこく繰り返すようですけれど、加減算しかできない、たかだか8ビットのCPUでこういう計算までさせることができる、というのはちょいとすごいことではありませんか?
これこそまさにプログラム、なのです。
と思います。
2010.7.9upload

前へ
次へ
ホームページトップへ戻る