 # PICMicrocontollerMathMethod

## Divide 16 bit int by 8 bit int to 8 bit int and remainder

```#define bf_carry 3, 0
#define bf_zero 3, 2

#define same 1
#define wreg 0

#define stc bsf bf_carry
#define clc bcf bf_carry

;-[ Div ]--------------------------------------------------------------
; Call w/: Number in f_divhi:f_divlo, divisor in W.
; Returns: Quotient in f_divlo, remainder in f_divhi. W preserved.
;          Carry set if error. Z if divide by zero, NZ if divide overflow.
; Notes:   Works by left shifted subtraction.
;          Size = 29, Speed(w/ call&ret) = 7 cycles if div by zero
;          Speed = 94 minimum, 129 maximum cycles

Div;
addlw 0          ; w+=0 (to test for div by zero)
stc              ; set carry in case of error
btfsc bf_zero    ; if zero
return          ;   return (error C,Z)

call DivSkipHiShift
iDivRepeat = 8
while iDivRepeat

call DivCode

iDivRepeat--
endw

rlf f_divlo, same ; C << lo << C

; If the first subtract didn't underflow, and the carry was shifted
; into the quotient, then it will be shifted back off the end by this
; last RLF. This will automatically raise carry to indicate an error.
; The divide will be accurate to quotients of 9-bits, but past that
; the quotient and remainder will be bogus and carry will be set.

bcf bf_zero  ; NZ (in case of overflow error)
return       ; we are done!

DivCode
rlf f_divlo, same    ; C << lo << C
rlf f_divhi, same    ; C << hi << C
btfss bf_carry       ; if Carry
goto DivSkipHiShift ;
subwf f_divhi, same  ;   hi-=w
stc                  ;   ignore carry
return               ;   done
; endif
DivSkipHiShift
subwf f_divhi, same  ; hi-=w
btfsc bf_carry       ; if carry set
return              ;   done
clc                  ; clear carry
return               ; done

```

Questions:

hi,
only one comment i suppose i donÂ´t understand

this instruction:
bcf bf_zero ; NZ (in case of overflow error)

Always clear FLAG Z --&gt; so always indicates an overflow error ?
James Newton of Massmind replies: At that point in the code, we know we are not dividing by zero; we already tested for that withbtfsc bf_zero ; if zero. Clearing bf_zero after we detect an overflow, just makes sure the routine does not send an ambiguous error message. At this point, we might have an overflow (see the previous lines) but we certainly do not have a divide by zero error.+

+

• spampic at KILLspamcanadaspeaks.com asks: " what language is this? it looks like mostly asm, but x = y and while loops are not assembly instructions." James Newton replies: That is pseudo code that should be translated into the equvilent ASM code before the code is used. Please consider posting a complete version if you get the code to work.+

+

Code:

• mark_jeronimus-gmail- shares this code:
```The next function divides a 16-bit number in MODREG1:MODREG0 by any N<=16 bit
number in TEMP1:TEMP0. The quotient will be stored in DIVREG1:DIVREG:0 and the
modulo in MODREG1:MODREG0.

(in this notation, MODREG1 is th HI byte, etc.)

It is optimized for dividing numbers by a constant.

Restraints:
- The divisor in TEMP1:TEMP0 should be left-aligned (eg, padded with zeroes on
the LSB side). This is easy if you divide by 8-bits.
- The high bit of the divisor (TEMP1.7) should be 1. If the high bit of the
divisor is not 1 then the result may overflow. This will cause the (17-N)-bit
quotient in DIVREG1:DIVREG0 to contain all ones and can be further detected by
comparing MODREG1:MODREG0 by the used divisor (which was btw destroyed by this
function). Bottomline, it is better to avoid this.
- No detection for a divisor of zero (which would mean a divisor of 0 bits long
which is nonsense)

Worst case timing: 6+(17-N)*23 (where N is the number of bits in the divisor)
N=4: T=305
N=8: T=213
N=12: T=121

Here's the universal version:

;;DIVIDE A 16-BIT NUMBER BY AN N-BIT NUMBER
;;IN:
;;    MODREG1:MODREG0 = 16-BIT DIVIDEND
;;    TEMP1:TEMP0     = N-BIT DIVISOR, LEFT ALIGNED, WITH TEMP1.7 = 1
;;OUT:
;;    DIVREG1:DIVREG0 = (17-N)-BIT WIDE QUOTIENT
;;    MODREG1:MODREG0 = N-BIT REMAINDER
;;DESTROYED:
;;    COUNT = 0
;;    TEMO1:TEMP0 = ORIGINAL TEMO1:TEMP0 << (17-N)
;;        THAT MEANS TEMO1:TEMP0 = 0 IF INPUT IS CORRECT
DIV16
MOVLW   17-N
MOVWF   COUNT
CLRF    DIVREG0
CLRF    DIVREG1
DIV16_LOOP
MOVF    TEMP0,W     ;W=MOD-DIVISOR
SUBWF   MODREG0,W
MOVF    TEMP1,W
BTFSS   STATUS,C    ;PROCESS BORROW
SUBWF   MODREG1,W

BTFSS   STATUS,C    ;IF W<0
GOTO    DIV16_NOSUB

MOVF    TEMP0,W     ;MOD=MOD-DIVISOR
SUBWF   MODREG0,F
BTFSS   STATUS,C
DECF    MODREG1,F
MOVF    TEMP1,W
SUBWF   MODREG1,F

BSF     STATUS,C
DIV16_NOSUB
RLF     DIVREG0,F   ;DIV << 1 + CARRY
RLF     DIVREG1,F

BCF     STATUS,C    ;DIVISOR>>=1
RRF     TEMP1,F
RRF     TEMP0,F

DECFSZ  COUNT,F
GOTO    DIV16_LOOP
RETURN

In the next example, it has been configured to divide a 16-bit number by a
6-bit number in WREG. It will put it in TEMP1 (and clear TEMP0) and shift it
to the left by 2 bits to align it left. The result is 11-bits wide in
DIVREG1:DIVREG0 and the remainder is of course 6-bits wide (same width as the
divisor) and still occupies MODREG1:MODREG0.

;;DIVIDE A 16-BIT NUMBER BY A 6-BIT WREG. RESULT IS 11-BIT WIDE
DIV16_6
;SHIFT LEFT BY 10 BITS
MOVWF   TEMP1
CLRF    TEMP0
BCF     STATUS,C
RLF     TEMP1,F
RLF     TEMP1,F

MOVLW   11
MOVWF   COUNT
CLRF    DIVREG0
CLRF    DIVREG1
DIV16_6_LOOP
MOVF    TEMP0,W     ;W=MOD-DIVISOR
SUBWF   MODREG0,W
MOVF    TEMP1,W
BTFSS   STATUS,C    ;PROCESS BORROW
SUBWF   MODREG1,W

BTFSS   STATUS,C    ;IF W<0
GOTO    DIV16_6_NOSUB

MOVF    TEMP0,W     ;MOD=MOD-DIVISOR
SUBWF   MODREG0,F
BTFSS   STATUS,C
DECF    MODREG1,F
MOVF    TEMP1,W
SUBWF   MODREG1,F

BSF     STATUS,C
DIV16_6_NOSUB
RLF     DIVREG0,F   ;DIV << 1 + CARRY
RLF     DIVREG1,F

BCF     STATUS,C    ;DIVISOR>>=1
RRF     TEMP1,F
RRF     TEMP0,F

DECFSZ  COUNT,F
GOTO    DIV16_6_LOOP
RETURN```
+

 file: /Techref/microchip/math/div/16by8lz.htm, 8KB, , updated: 2010/2/24 13:30, local time: 2020/2/20 22:56, TOP NEW HELP FIND:  35.173.57.84:LOG IN

 ©2020 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?Please DO link to this page! Digg it! / MAKE! PIC Microcontoller Math Method

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.

Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
 Did you find what you needed? "No. I'm looking for: " "No. Take me to the search page." "No. Take me to the top so I can drill down by catagory" "No. I'm willing to pay for help, please refer me to a qualified consultant" "No. But I'm interested. me at when this page is expanded."

.