[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: