ワンボードマイコンをつくろう!(パソコンの原点はここから始まった)
TK80ソフトコンパチブル!8080、Z80マシン語からBASICまでこれ1台でこなせます
当記事は2009年11月から「TTLでCPUをつくろう!」というタイトルの もとにほとんど毎日連載をしてきたものを再編集したものです。 2011.6.30
前へ
次へ
目次へ戻る
ホームページトップへ戻る
☆ND80ZVでBASICを。
とんでもない機能追加を思いついてしまいました。
ND80ZVでBASICを実行できるようにしようというのです。
それも浮動小数点演算ができて、三角関数や対数計算までできる本物のBASICです!

[第57回]

●実数型のデータ構造

前回書いた内容を今朝になってから読み直していましたら、ちょっと説明不足だなあ、という感じがしましたので、追記いたしました。まだご覧いただいてない方はまずそちら([第56回]追記)をお読みくださいませ。

さて本日はZ80BASICの実数型変数(および実数型定数)のデータ構造について説明をいたします。
整数型データの構造についてはすでに何回か説明をしておりますが、実数型というのははじめてかと思います。

整数型は2バイト16ビットの長さです。
整数型は2バイトをつないで16ビットにした、その2進数そのままの値になります。
符号なしの場合には0000〜FFFFの値をとります。
これは10進数であらわすと0〜65535になります。
符号付の数の場合、最上位ビットが0の数0000〜7FFFが正の数で、10進数の0〜32767になります。
最上位ビットが1の数FFFF〜8000が負の数になります。10進数の−1〜−32768です。

これに対して実数型は4バイトの長さです。
整数型の2倍ですが、その構造は複雑です。
実数型は小数点を含む数を扱うことと、もうひとつ非常に大きな範囲の数を扱うための工夫がなされています。

10進数でも非常に大きな値(または非常に小さな値)を表現するときに指数を使って表します。
たとえば、0.00000123という数はそのままではやたら0が多くてこのままでは実際の大きさがどれほどのものかピンときませんし、数式の中でこのまま扱うのも厄介です。うっかり0の数を書き間違えてしまうかもしれません。
そこで、これを0.123×10−5のように表します。

Z80BASICの実数型もそれと同じ考え方をしています。
なおここで扱う実数型の構造は標準的な考え方のものとは少し異なっているところがあります。
標準とされる構造は、実際に計算処理をする上でちょっと面倒なところがあるため、標準の方法よりも有効桁がちょっと少なくなりますが独自の構造を採用しています。

4バイトのうち最上位の1バイトは指数部です。
1バイト8ビットを符号付の指数として扱いますから、00〜7Fが正の指数0〜+127を、そしてFF〜80が負の指数−1〜−128を表します。ただし2進数ですから、10ではなくて、2を示します。
つまり指数部は2−128〜2+127の範囲の大きさを示すことができます。

残り3バイト24ビットが数の本体(仮数)部分です。
ここも最上位ビットは符号を表します。
その下の23ビットで数の並びを示しますが、ここが普通の2進数と違っています。

まず普通の2進数で10進数の12345を示す場合について考えてみます。
10進数の12345は16進数で表現すると、3039になりますから、それを2進数24ビットで表現すると、
00000000 00110000 00111001 ……(1)
になります。最上位ビットは符号ビットです。

しかし実数型ではこれを、10進数の指数表現と同じように、1よりも小さい数に変換して、さらに小数点のすぐ下位つまり小数第1位が必ず1であるような数に直します。
01100000 01110010 00000000 ……(2)
のようにします。
これが正規化(normalize)とよばれる作業です。

最上位が符号ビットで、そのすぐ下に2進数の小数点があることにします。
するとその右に続く最初の1は2−1つまり0.5で、さらにその右の1は2−2つまり0.25になります。

それでは仮数部をそのようにしたときに、指数部はいったいどのような値にするともとの3039(10進数の12345)と同値になるでしょうか。
ちょっと見当もつかない、かも知れませんが、実はそれほどむつかしいことではありません。

さきほどの正規化をする前の数(1)では小数点が最下位ビットの右にありました。
これを、一番上位の1が小数点の右にくるところまで、シフトしたものが(2)である、と考えることができますから、
110000 00111001
これだけの部分を右にシフトしたことになります。
1ビット右にシフトすると同時に指数が1加算されることになりますから、すると、14ビットシフトしていますから、指数部は14つまり214になります。
14を16進数に直すと0Eですから、指数部は00001110になります。

以上のことから、10進数の12345を2進数の実数型に変換すると、
00001110 01100000 01110010 00000000 ……(3)
になります。

なぜこんな面倒なことをしているかと言いますと、最初に書きましたように、計算で扱える数の範囲をうんと広げて通常の計算なら大抵はオーバーフローしないようにするためなのです。
数をこのような形に変換して計算を行う方法を浮動小数点計算といいます。
これに対して整数部と小数部の境に小数点がある、私達が普通に扱っている数の表現方法を固定小数点表示といいます。
固定小数点による計算は正確な結果を求めることができますが、非常に大きな桁数の演算レジスタが必要になってしまいます。
浮動小数点方式は計算結果に誤差が生じてしまいますが、演算レジスタの桁数が少なくて済みますから、コンピュータでの数値演算はこの方法で行うことが一般的です。

さて参考までに、上で行った作業を実際に確かめてみることにしましょう。
実際にBASICのプログラムを実行してその結果を見てみることにします。

logfile nd80zlog\07042240.txt open

ND80ZVに接続しました
0001 0000 - z1000 00C3 - *** nd80z3 basic ****
>10abc=12345
>list
    10 ABC=12345
>help
TEXT 8004-8028
ヘンスウ DFFB-DFFF
>dm 8000,8028
8000  04 80 10 80 00 80 FF DF 10 80 0C 00 B3 53 44 94  .......゚....ウSD.
8010  FC DF 41 42 43 00 00 85 0A 00 04 00 0A 00 08 F0  .゚ABC...........
8020  0C 00 9A FA 39 30 0D 0B F4 DF 43 00 55 54 00 85  ....90...゚C.UT..
>run

>dm dff0,dfff
DFF0  FD FF 5D 06 00 00 DB 08 00 00 50 03 00 72 60 0E  ..]...ロ...P..r`.
>/exit

ndremote.exeを終了しました
logfile closed at Sun Jul 04 22:40:00 2010

たった1行だけですが、
10 ABC=12345
と書いて、このプログラムを実行してみました。

変数ABCはアドレスDFFCからの4バイト(DFFC〜DFFF)にあります。
runコマンドで実行したあと、DMコマンドでアドレスDFFC〜DFFFの値を確認しています。
整数の場合と同じように、データの並びは下位バイトから上位バイトの順になっています。
これをさきほどの説明と同じように上位バイト〜下位バイトの順に並び直してみます。

0E 60 72 00

さきほどの説明での結果(3)と同じ値になっています。
CPUをつくろう!第542回(2010.7.4upload)を再編集

ワンボードマイコンをつくろう![第57回]
2011.6.30upload

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