A83: Re: Signed Division
[Prev][Next][Index][Thread]
A83: Re: Signed Division
The routine you posted came from Icarus' website, presumably written by
Jimmy Mardell. I don't know what kind of numbers you need it for (16 bit?),
but the thing to remember is that people wrote and optimized this stuff 20
years ago. ticalc.org is definitely not the only place on the Internet to
look.
http://icarus.ticalc.org/features/multdiv.h
The only other routine that I remember seeing is this one on Jeff's page.
It's unsigned, but you can change it to work with signed numbers the same
way as the one above.
http://home.hiwaay.net/~jfrohwei/gameboy/div16161.asm
I decided to comment the first one, out of curiosity. The comment is
correct about it being really lousily coded. Basically, it subtracts the
divided from the divisor until there's nothing left, and it counts the
number of times it does it. The other routine I linked to should be much
more efficient.
> I am writing a program for the 83+ that uses signed division. I decided
> against using the OPx ROM calls for this becuase they are floating point
> and presumably quite slow. I used to have four or five lines of code to
> handle my unsigned division, the signed routine is huge by comparison. I
> found a signed division routine on the 'net', but I'm wondering how
> efficient it is. I don't understand how it works, I just assume that it
> does. Is this routine (below) any good, can anybody point me the
> direction of a better faster one...?
; 16 bit signed multiplication routine (REALLY LOUSY CODED!!!)
;
; If DE=0, returns with carry flag set.
; If DE<>0, returns with carry cleared and HL = BC/DE
;
; Destroys: AF, BC, DE
Div:
ld a,d ; check for division by 0 and return
or e
scf
ret z
xor a ; clear negative number count
bit 7,b ; test to see if dividend is negative
jr z,Pos3
inc a ; count it as being negative
ld hl,0 ; make it positive by subtracting from 0
sbc hl,bc
ld b,h
ld c,l
Pos3:
bit 7,d ; same as above, but for divisor
jr z,Pos4
inc a
ld hl,0
sbc hl,de
ld d,h
ld e,l
Pos4:
ld h,b ; going to subtract from dividend
ld l,c
ld bc,0 ; set subtract counter to 0
DivLoop:
or a
sbc hl,de ; subtract divisor from dividend
jr c,FixSign ; if the divisor was bigger, then it is done
inc bc ; increase subtract counter
jr DivLoop ; continue until a carry occurs
FixSign:
ld h,b
ld l,c
or a
res 7,h ; make dividend positive
bit 0,a ; check if both signed or unsigned (0 or 2)
ret z ; then the result is correct
ld hl,0 ; otherwise, negate the result
sbc hl,bc
or a
ret
References: