[A83] Re: Divide by 12
[Prev][Next][Index][Thread]
[A83] Re: Divide by 12
> Here is some code for dividing an unsigned 16-bit integer
> by 12. The simplest algorithm to compute n / 12 that I am
> aware of is:
>
> q = (n >> 1) + (n >> 3)
> q = q + (q >> 4)
> q = q + (q >> 8)
> q = q >> 3
> r = n - q * 12
> q = q + ((r + 4) >> 4)
The computation of ((r + 4) >> 4) computes a correction factor
that is either 0 or 1, based on the remainder one gets after
subtracting the product of preliminary quotient and divisor
from the dividend. So one might want to replace this last step
with
q = q + (r >= 12)
This leads to the following variant of the unsigned divide-by-12
code. Note that with a few more instructions we could return the
remainder as well. In the computation above "r" is a preliminary
remainder and may be too big by 12. When correcting the quotient
we could also fixup the remainder and return it in DE.
-- Norbert
DivBy12:LD D, H
LD E, L ; BC = n
SRL H
RR L ; HL = n >> 1
LD B, H
LD C, L ; BC = n >> 1
SRL H
RR L
SRL H
RR L ; HL = n >> 3
ADD HL, BC ; q = (n >> 1) + (n >> 3)
LD B, H
LD C, L ; BC = q
SRL H
RR L ;
SRL H
RR L ;
SRL H
RR L ;
SRL H
RR L ; HL = q >> 4
ADD HL, BC ; q = q + (q >> 4)
LD B, H
LD C, L ; BC = q
LD L, H ;
LD H, 0 ; HL = q >> 8
ADD HL, BC ; q = q + (q >> 8)
SRL H
RR L ;
SRL H
RR L ;
SRL H
RR L ; HL = q >> 3
LD B, H
LD C, L ; BC = q
ADD HL, HL ; 2 * q
ADD HL, BC ; 3 * q
ADD HL, HL ; 6 * q
ADD HL, HL ; 12 * q, CF = 0
EX HL, DE ; HL = n, DE = q * 12
SBC HL, DE ; r = n - q * 12 (CF = 0)
LD DE, 12 ; 12
SBC HL, DE ; r - 12
SBC HL, HL ; (r < 12) ? -1 : 0
INC HL ; (r < 12) ? 0 : 1
ADD HL, BC ; q = q + (r >= 12) = n / 12
Follow-Ups:
References: