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

●SQR(平方根)関数

[第533回]でBASICが動き出しました、と書いたのっけから、バグにはまってしまって、それから前回の[第544回]まで、なんと12回もの間、バグつぶしについて書いてきました。
日数で言いますと、6月24日から7月6日までかかって書いてきたことになります。
もっとも書くのにはそれだけの日数がかかったのですけれど、そこで書きましたバグ発見までのあれこれの作業は、実際には6月23日の1日間の出来事に過ぎませんでした。
いやあ、なんとも長い一日でした。

そもそもバグでひっかかってしまったテストプログラムはSQR(平方根)関数をFOR NEXTで、1〜10まで回しながら表示させる、というものでした。
バグそのものはSQR関数にではなくて、実数型のFOR NEXTにありました(もっと正確に言いますと、実数型の加算ルーチンにミスがありました)。
前回はやっとバグが退治できて、FOR NEXT文で1〜10までの平方根を計算して表示できました。

これは前にも書いたことなのですが、このZ80BASICは、表示こそUSBを通じてDOSプロンプトの画面に対して行っていますが、計算そのものはたとえわずかでもパソコンの力は借りていません。
平方根を求めるためには、当然複雑な数値演算を行っているのですけれど、それは全てZ80がやっているのです。
ご存知のようにZ80には乗除算命令はありません。
8ビットおよび16ビットの2進数の加算と減算しかできないのです。
それでもこれだけのことができるのです。
これだけの、と言いますか、これほどのこと、と言い換えてもよいのでは、と思います。

ひょっとすると平方根表データがプログラムに仕込んであるのではないか?
などとお疑いの向きもあろうか、と思いますが、とんでもありません。
表などどこにも仕込んではおりません。
ぜーんぶ、はなから計算で求めているのです。
ええ。激しく2進数の加算と減算(それとローテイト)命令を使って、です。

計算で求めているからには、もちろんフジサンロクオームナクやヒトヨヒトヨニヒトミゴロなどでなくても、自由な値に対して平方根を求めることができます。
次の画面コピーは、その参考例です。



今までと同じFOR NEXT文を使って、今度は0〜1の間の平方根を0.1きざみで求めてみました。
FOR文のSTEPは上の画面のプログラムのように、きざみ値を指定するときに使います。

いかがでしょうか。
ちょいとすごいなあ、と思っていただけましたでしょうか。

あ。でも、実は、こんなものじゃあないのです。
このZ80BASICはハンパじゃないのですよ。
もっとすごいことができてしまうのです。

●倍精度実数演算

まずは次のログファイルをご覧ください。

logfile nd80zlog\07070725.txt open

ND80ZVに接続しました
0001 0000 - z1000 00C3 - *** nd80z3 basic ****
>auto
>    10    10for a#=0 to 10
>    20    20print a#,sqr(a#)
>    30    30next a#
>    40
*** send break(3)***
>run
0            0
1            1
2            1.414213562373095
3            1.732050807568877
4            2
5            2.23606797749979
6            2.449489742783178
7            2.64575131106459
8            2.82842712474619
9            3
10           3.162277660168379

>list
    10 FOR A#=0 TO 10
    20 PRINT A#,SQR(A#)
    30 NEXT A#
>    20 PRINT A#,a#^0.5
>run
0            0
1            1
2            1.414213562373095
3            1.732050807568877
4            2
5            2.23606797749979
6            2.449489742783178
7            2.64575131106459
8            2.82842712474619
9            3
10           3.162277660168379

>/exit

ndremote.exeを終了しました
logfile closed at Wed Jul 07 07:30:13 2010

さきほどまでと同じSQR関数ですけれど、今度は変数Aに#がついています。
変数に#がつくと倍精度で演算を行います。
整数型の演算は2バイトで行います。
そして今まで説明をしてきました実数型の演算は4バイトで行います。
仮数部の長さは24ビットです。
それに対して、変数に#をつけた倍精度実数型の演算は8バイトで行います。
仮数部の長さはなんと56ビットもあります。

同じ平方根演算でもそれだけの長さの数値で計算をすると精度が桁違いによくなります。
もっともそれだけ計算時間も長くかかりますけれど。

上のテストプログラムを実行して求めた倍精度実数型の平方根が果たして正しい値なのかどうか、皆様も念の為に計算して確認してみてください。
平方根はWindowsの電卓で計算することができます。
電卓の種類を関数電卓にしてください。
平方根は、[x^y]で求めます。
たとえば3の平方根(ルート3)ならば、
最初に数字の[3]を入力して、次に[x^y]キーを押して、最後に0.5を入力してから[=]キーを押します。
平方根は1/2乗ですから、つまり0.5乗を求めれば、それが平方根になります。

●累乗

おお。そうなのです。
わがZ80BASICは、なんと平方根だけではなくて累乗もちゃんとこなしてくれるのです。
上のログの後半は、SQR()関数の代わりに、0.5乗の計算をさせています。
行番号20を書き換えて、SQR(A#)を、A#^0.5にしています。
累乗は関数電卓と同じ記号 ^ を使います。
もちろん同じ計算結果が得られます。

●ログファイルのタイムスタンプを直しました

実は前の回でお見せしておりましたログファイルのタイムスタンプにバグがありました。
ログファイルはオープンした時の月日時分をファイル名にします。
そこのところは間違ってはいなかったのですが、クローズするときもオープンした時の日付時間がそのまま表示されていました。
そのことに気が付きましたので、C++プログラムを修正しました。
上のログファイルは、ちゃんとクローズしたときの時間を表示しています。
2010.7.7upload

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