# PICMicrocontollerMathMethod

## Divide 24 bits by 16

Andrew David (akdavid at ultronics.co.uk), Software Manager, Ultronics Ltd, Cheltenham says:

This division routine uses the standard binary long-division algorithm. The loop iterates once for each bit in the numerator, so it goes round 24 times. For each loop the numerator (sorry, but I can never remember which is the dividend and the divisor - I guess the divisor is the denominator, but I'd hate to get it wrong) is left shifted 1 bit into the remainder, then the remainder is compared with the denominator. If the remainder is greater than the denominator, the denominator is subtracted from the remainder and a 1 is shifted into the quotient, otherwise a 0 is shifted into the quotient. If you can't see how the routine works, try running through an example on paper, in binary, then think about how you'd write the routine.
```;=============================================================================
; DIV24_16u
;
;       Divides a 24bit number by a 16bit number. Unsigned.
;
;       Inputs:
;		24-but numerator in ACCcLO:ACCdHI:ACCdLO
;		16-bit denominator in ACCbHI:ACCbLO
;
;       Outputs:
;		24-bit quotient in ACCcLO:ACCdHI:ACCdLO
;		16-bit rem in ACCaHI:ACCaLO
;
;	Locals used:
;		R5Hi
;
;
; Inputs are not preserved.
;
; No timing analysis performed.
; Andrew David, Software Manager, Ultronics Ltd, Cheltenham
; akdavid at ultronics.co.uk          http://www.ultronics.com
;
;=============================================================================

DIV24_16u:
movlw   .24             ; for 24 shifts
movwf   R5Hi            ;

clrf    ACCaHI,f        ; clear remainder.
clrf    ACCaLO,f        ;

d2416lp:rlcf    ACCdLO,f        ; build up remainder.
rlcf    ACCdHI,f        ;
rlcf    ACCcLO,f        ;
rlcf    ACCaLO,f        ;
rlcf    ACCaHI,f        ;

; remainder is 16-bit, but may have spilled over into carry.

btfss   ALUSTA,C        ; check for remainder spill into carry.
goto    d2416s          ;

movfp   ACCbLO,WREG     ;
subwfb  ACCaLO,f        ; Carry bit is the 17th bit of this
subtract!
movfp   ACCbHI,WREG     ;
subwfb  ACCaHI,f        ;
bsf     ALUSTA,C        ; bit is known to be zero here.
goto    d2416ns         ;

d2416s: movfp   ACCbLO,WREG     ; Compare remainder with divisor.
subwf   ACCaLO,w        ;
movfp   ACCbHI,WREG     ;
subwfb  ACCaHI,w        ;
btfss   ALUSTA,C        ;
goto    d2416ns         ; (remainder < divisor), shift in a '0'
movfp   ACCbLO,WREG     ; The remainder is larger, so subtract
the
subwf   ACCaLO,f        ; ... divisor FROM the remainder and
movfp   ACCbHI,WREG     ; ... shift a '1' into the quot.
subwfb  ACCaHI,f        ;

d2416ns:decfsz  R5Hi,f          ; check all bits
goto    d2416lp         ;
rlcf    ACCdLO,f        ; shift in final quotient bit.
rlcf    ACCdHI,f        ;
rlcf    ACCcLO,f        ;

return

```

jaakko-haakana- Says:

This code does not work if the divisor is smaller than 0x100.

Replace the five instructions at d2416s with the following to make it work (converted for 16f84):

```        movf   ACCbHI,W     ; divisor hi
subwf  ACCaHI,w        ; remainder hi (w = remainder - divisor)
btfss	STATUS, C
goto	d2416ns		; (remainder < divisor), shift in a '0'
movf   ACCbLO,W
subwf   ACCaLO,w
btfss   STATUS,C
```
+
The above (anonymous) poster has not convinced me that the original code doesn't work -- my test cases for divisor < 0x100 are all correct.

The original code is for the 17c series pics, hence the use of the subwfb instruction. The purpose of the first 5 lines of code at d2416s is to compare the current remainder with the (constant) divisor. Using a 16-bit subtract abd checking the status of carry is standard, I can't get this code to fail. The carry that is subsequently shifted into the quotient is correct as either remainder => divisor (when remainder - divisor is +ve (>= 0) carry = 1) or remainder < divisor (carry = 0).

I've just tried several test cases with divisor < 0x100, I can't see any problem. As a benchmark I've used BaseCalc.

The alternative code looks like it will work but I don't believe there's a reason for using it; you'd normally need a good reason to replace 5 (working) lines of code with 7.

Note that if you want to use this code for 14-bit core you'll need to change more code than suggested.

Now that I've finished saying that the code works, I refer the reader to the standard disclaimer in that I'm not responsible for your use of this code. Clever people use Dimitry's, Nikolai's or Scott's code, anyway.

+

Questions:

• Vinicius Bordinhão Carvalho asks: " i would like divide a 16 bits by 16bits and save in 16bits bits the result. Help" +
I have tried to modify and use the code for a PIC 18F2480 (16 bit) but I can't get it to work, even with the modify of mr. jaakko-haakana. This is what I got:
```DIV24_16u:
movlw   	d'24'			; for 24 shifts
movwf   	R5Hi            ;

clrf    	REMBH			; clear remainder.
clrf    	REMBL			;

d2416lp:	rlcf    	DATO1L,f        ; build up remainder.
rlcf    	DATO1H,f        ;
rlcf    	DATO1U,f        ;
rlcf    	REMBL,f        	;
rlcf    	REMBH,f        	;

; remainder is 16-bit, but may have spilled over into carry.

btfss   	STATUS,C        ; check for remainder spill into carry.
goto    	d2416s          ;

movf   		DATO2L,W     	;
subwfb  	REMBL,f        	; Carry bit is the 17th bit of this subtract!

movf   		DATO2H,W     	;
subwfb  	REMBH,f        	;
bsf     	STATUS,C        ; bit is known to be zero here.
goto    	d2416ns         ;

d2416s: 	movf   		DATO2H,W     	; divisor hi
subwf  		REMBH,w        	; remainder hi (w = remainder - divisor)
btfss		STATUS, C
goto		d2416ns			; (remainder < divisor), shift in a '0'
movf   		DATO2L,W
subwf   	REMBL,w
btfss   	STATUS,C
goto    	d2416ns         ; (remainder < divisor), shift in a '0'
movf   		DATO2L,W     	; The remainder is larger, so subtract
subwf   	REMBL,f        	; ... divisor FROM the remainder and
movf   		DATO2H,W     	; ... shift a '1' into the quot.
subwfb  	REMBH,f        	;

d2416ns:	decfsz  	R5Hi,f          ; check all bits
goto    	d2416lp         ;
rlcf    	DATO1L,f        ; shift in final quotient bit.
rlcf    	DATO1H,f        ;
rlcf    	DATO1U,f        ;

return
```
Can anybody advise me about where is the error? Thanks in advance. Lorenzo. Email: tecnico at innotec.it
+

 file: /Techref/microchip/math/div/24by16ad.htm, 8KB, , updated: 2011/1/28 04:07, local time: 2022/1/25 21:13, TOP NEW HELP FIND:  52.203.18.65:LOG IN

 ©2022 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 a nice message (short messages are blocked as spam) 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."

 PICList 2022 contributors: o List host: MIT, Site host massmind.org, Top posters @20220125 * Page Editors: James Newton, David Cary, and YOU! * Roman Black of Black Robotics donates from sales of Linistep stepper controller kits. * Ashley Roll of Digital Nemesis donates from sales of RCL-1 RS232 to TTL converters. * Monthly Subscribers: Gregg Rew. on-going support is MOST appreciated! * Contributors: Richard Seriani, Sr.

.