割り算

目次

概要

Z80 基本

Z80 引き放し法変数共用さらに引き放し法

6502基本

変数共用さらに引き放し法

速度判定


Z80 引き放し法

1桁ごとの、計算後の処理を軽減したものです。



	LD L,0 ; 7 (8)
	EXX ; 4 (5)
	LD HL,12345 ; 10 (11)
	LD A,10 ; 7 (8)
	LD B,7 ; 7 (8)

; 前処理。割る数 A を左詰め。
PRE:
	INC B ; 4 (5)
	RLCA ; 4 (5)
	JR NC,PRE ; 12 / 7 (13 / 8)
	RRCA ; 4 (5)

	LD D,A ; 4 (5)
	LD E,0 ; 7 (8)

	AND A ; 4 (5) ; キャリーフラグを消す

; 筆算の引き放し法で割り算
PLUS:
	SBC HL,DE ; 15 (17)
	JR C,MINUS_AFTER ; 12 / 7 (13 / 8)

PLUS_AFTER:
	EXX ; 4 (5)
	ADD HL,HL ; 11 (12)
	INC L ; 4 (5)
	EXX ; 4 (5)
	SRL D ; 8 (10)
	RR E ; 8 (10)
	DJNZ PLUS ; 13 / 8 (14 / 9)

	LD A,L ; 4 (5)
	JP END ; 10 (11)

MINUS:
	ADD HL,DE ; 11 (12)
	JR NC,PLUS_AFTER ; 12 / 7 (13 / 8)

MINUS_AFTER:
	EXX ; 4 (5)
	ADD HL,HL ; 11 (12)
	EXX ; 4 (5)
	SRL D ; 8 (10)
	RR E ; 8 (10)
	DJNZ MINUS ; 13 / 8 (14 / 9)

	LD A,L ; 4 (5)
	ADD A,E ; 4 (5)

END:
	EXX ; 4 (5)
; HL に商、A に余り

基本のプログラムでは、1桁の演算後、結果がマイナスの時は元に戻し、次の桁に進んでいました。

次の桁では、除数を1ビット右シフト…つまり 1/2 してから引いています。


数式で書くと、HL = HL - DE の後、 HL<0 ならば、 HL = HL + DE - DE/2 します。

DE が2回出てくるのでまとめると HL = HL + DE/2 と同じです。

そして、DE/2 というのは「次の桁」の処理であることを意味します。


つまり、結果がマイナスなら次の桁は「引き算」ではなく「足し算」をするようにしてやれば、処理が軽減できます。


この計算方法を「引き放し法」と呼びます。

(読みは「ひきはなし」ですが、意味としては「ひきっぱなし」です。引いた後元に戻さないため)


高速なのですが、プラスの場合とマイナスの場合で類似処理が2つになるため、プログラムは長くなっています。


1桁分の計算は、結果がプラスの時、 86 クロック(最後だけ +11)、マイナスの時、 76 クロック(最後だけ + 5)。


ただし、連続した途中結果の符号が異なるとき、+5クロック。

ループ内の計算では「連続した途中結果の符号が異なる」のは、8回あります。


また、最後がマイナスで終わった際、「剰余」の補正に5クロックの追加時間が必要になります。


そのほかの条件は、基本と同じです。


40 + 138 + 86*8 + 76*5 +5*8 +5 +5 = 1296


総計 1296クロックです。


変数共用

2014.9.1 追記

6502 で先に投稿された「変数共用」を、Z80 に移植したものが投稿されました。



	LD HL, 12345 ; 10 (11)
	LD C, 10 ; 7 (8)
	LD B, 16 ; 7 (8)
	XOR A ; 4 (5)
LOOP:
	ADD HL, HL ; 11 (12)
	RLA ; 4 (5)
	CP C ; 4 (5)
	JR C, SHIFT ; 12 / 7 (13 / 8)

	SUB C ; 4 (5)
	INC L ; 4 (5)
SHIFT:
	DJNZ LOOP ; 13 / 8 (14 / 9)

移植とはいえ、処理は Z80 で速くなるように若干順序を変えています。しかし、基本的には同じことをしています。

HL と A で 24bit のローテートを行い、C を除数として A と演算しています。


投稿プログラムでは、ここまでのプログラムに合わせて A に除数を設定したうえで C にコピーしてくださっていました。しかし、レジスタの使い方に制約は設けていないので、ここでは最初から C に除数を入れています。


前処理に 32 クロック。

1桁の計算は、結果がプラスだと54クロック、マイナスだと 49クロック。最後は5クロック速くなります。

16桁を処理しますが、マイナスが 11 回、プラスが 5回です。


32 + 49*11 + 54*5 -5 = 836

総計 836クロックです。


次ページ: さらに引き放し法


前ページ 1 2 3 4 次ページ

(ページ作成 2014-08-20)
(最終更新 2015-04-28)
第2版 …他の版 初版

前記事:コマンド入力     戻る     次記事:10進表示
トップページへ

-- share --

7000

-- follow --




- Reverse Link -