# PICMicrocontollerMathMethod

## Divide 24 bit int by 16 bit int to 24 bit int

from by Nikolai Golovchenko

```FXD2416U:
CLRF REMB0
CLRF REMB1
MOVLW 24
MOVWF LOOPCOUNT
LOOPU2416
RLF ACCB0, W    ;left shift of accb0's msb to reminder
RLF REMB1, F
RLF REMB0, F
MOVF BARGB1, W  ;REMB -= BARGB
SUBWF REMB1, F
MOVF BARGB0, W
BTFSS _C
INCFSZ BARGB0,W
SUBWF REMB0, F

BTFSC _C
GOTO UOK46LL    ;if no borrow

MOVF BARGB1, W  ;REMB += BARGB
MOVF BARGB0, W
BTFSC _C
INCFSZ BARGB0,W

BCF _C
UOK46LL
RLF AARGB2, F
RLF AARGB1, F
RLF AARGB0, F
DECFSZ LOOPCOUNT, F
GOTO LOOPU2416

RETURN

```
The routine above is actually 24 by 15 bits division. Below is a 24 by 16 bits division routine:
```
;Inputs:
;   Dividend - AARGB0:AARGB1:AARGB2 (0 - most significant!)
;   Divisor  - BARGB0:BARGB1
;Temporary:
;   Counter  - LOOPCOUNT
;   Remainder- REMB0:REMB1
;Output:
;   Quotient - AARGB0:AARGB1:AARGB2
;
;       Size: 28
; Max timing: 4+24*(6+6+4+3+6)-1+3+2=608 cycles (with return)
; Min timing: 4+24*(6+6+5+6)-1+3+2=560 cycles (with return)
;

FXD2416U:
CLRF REMB0
CLRF REMB1
MOVLW 24
MOVWF LOOPCOUNT
LOOPU2416
RLF AARGB2, F           ;shift left divider to pass next bit to remainder
RLF AARGB1, F           ;and shift in next bit of result
RLF AARGB0, F

RLF REMB1, F            ;shift carry into remainder
RLF REMB0, F

RLF LOOPCOUNT, F        ;save carry in counter

MOVF BARGB1, W          ;substract divisor from remainder
SUBWF REMB1, F
MOVF BARGB0, W
BTFSS _C
INCFSZ BARGB0, W
SUBWF REMB0, W          ;keep that byte in W untill we make sure about borrow

SKPNC                   ;if no borrow
BSF LOOPCOUNT, 0       ;set bit 0 of counter (saved carry)

BTFSC LOOPCOUNT, 0      ;if no borrow
GOTO UOK46LL           ;jump

MOVF BARGB1, W          ;restore remainder if borrow
MOVF REMB0, W           ;read high byte of remainder to W
;to not change it by next instruction
UOK46LL
MOVWF REMB0             ;store high byte of remainder
CLRC                    ;copy bit 0 to carry
RRF LOOPCOUNT, F        ;and restore counter
DECFSZ LOOPCOUNT, f     ;decrement counter
GOTO LOOPU2416         ;and repeat loop if not zero

RLF AARGB2, F           ;shift in last bit of result
RLF AARGB1, F
RLF AARGB0, F
RETURN

```

Nikolai Golovchenko shares this code:

```

Here is a slightly optimized version - 1 instruction shorter, 24 cycles faster!

;Inputs:
;   Dividend - AARGB0:AARGB1:AARGB2 (0 - most significant!)
;   Divisor  - BARGB0:BARGB1
;Temporary:
;   Counter  - LOOPCOUNT
;   Remainder- REMB0:REMB1
;Output:
;   Quotient - AARGB0:AARGB1:AARGB2
;
; Size: 27
; Max timing: 4+24*(6+6+4+3+5)-1+3+2=584 cycles (with return)
; Min timing: 4+24*(6+6+5+5)-1+3+2=536 cycles (with return)
;
;25-Sep-2000    Original version
;               review.

FXD2416U:
CLRF REMB0
CLRF REMB1
MOVLW 24
MOVWF LOOPCOUNT
LOOPU2416
RLF AARGB2, F           ;shift dividend left to move next bit to remainder
RLF AARGB1, F           ;and shift in next bit of result
RLF AARGB0, F           ;

RLF REMB1, F            ;shift carry (next dividend bit) into remainder
RLF REMB0, F

RLF LOOPCOUNT, F        ;save carry in counter, since remainder
;can be 17 bit long in some cases (e.g.
;0x800000/0xFFFF)

MOVF BARGB1, W          ;substract divisor from 16-bit remainder
SUBWF REMB1, F          ;
MOVF BARGB0, W          ;
BTFSS STATUS, C         ;
INCFSZ BARGB0, W        ;
SUBWF REMB0, F          ;

;here we also need to take into account the 17th bit of remainder, which
;is in LOOPCOUNT.0. If we don't have a borrow after subtracting from lower
;16 bits of remainder, then there is no borrow regardless of 17th bit
;value. But, if we have the borrow, then that will depend on 17th bit
;value. If it is 1, then no final borrow will occur. If it is 0, borrow
;will occur.

SKPNC                   ;if no borrow after 16 bit subtraction
BSF LOOPCOUNT, 0       ;then no no borrow in result. Overwrite
;LOOPCOUNT.0 with 1 to indicate no
;borrow.
;if borrow did occur, LOOPCOUNT.0 will
;hold the eventual borrow value (0-borrow,
;1-no borrow)

BTFSC LOOPCOUNT, 0      ;if no borrow after 17-bit subtraction
GOTO UOK46LL           ;skip remainder restoration.

ADDWF REMB0, F          ;restore higher byte of remainder. (w
;contains the value subtracted from it
;previously)
MOVF BARGB1, W          ;restore lower byte of remainder

UOK46LL
CLRC                    ;copy bit LOOPCOUNT.0 to carry
RRF LOOPCOUNT, F        ;and restore counter

DECFSZ LOOPCOUNT, f     ;decrement counter
GOTO LOOPU2416         ;and repeat loop if not zero. carry
;contains next quotient bit (if borrow,
;it is 0, if not, it is 1).

RLF AARGB2, F           ;shift in last bit of quotient
RLF AARGB1, F
RLF AARGB0, F
RETURN
```

Nikolai Golovchenko shares this code:

Well, the routine can be made even simpler! This version is 5 instructions shorter and 48 cycles faster. Thanks to Zlatko Petkov for an idea of removing the extra shifts after the loop. Nikolai Golovchenko. 5-Dec-2004.
```FXD2416U:
CLRF REMB0
CLRF REMB1
MOVLW .24
MOVWF LOOPCOUNT
LOOPU2416
RLF AARGB2, W           ;shift dividend left to move next bit to remainder
RLF AARGB1, F           ;
RLF AARGB0, F           ;

RLF REMB1, F            ;shift carry (next dividend bit) into remainder
RLF REMB0, F

RLF AARGB2, F           ;finish shifting the dividend and save  carry in AARGB2.0,
;since remainder can be 17 bit long in some cases
;(e.g. 0x800000/0xFFFF). This bit will also serve
;as the next result bit.

MOVF BARGB1, W          ;substract divisor from 16-bit remainder
SUBWF REMB1, F          ;
MOVF BARGB0, W          ;
BTFSS STATUS, C         ;
INCFSZ BARGB0, W        ;
SUBWF REMB0, F          ;

;here we also need to take into account the 17th bit of remainder, which
;is in AARGB2.0. If we don't have a borrow after subtracting from lower
;16 bits of remainder, then there is no borrow regardless of 17th bit
;value. But, if we have the borrow, then that will depend on 17th bit
;value. If it is 1, then no final borrow will occur. If it is 0, borrow
;will occur. These values match the borrow flag polarity.

SKPNC                   ;if no borrow after 16 bit subtraction
BSF AARGB2, 0          ;then there is no borrow in result. Overwrite
;AARGB2.0 with 1 to indicate no
;borrow.
;if borrow did occur, AARGB2.0 already
;holds the final borrow value (0-borrow,
;1-no borrow)

BTFSC AARGB2, 0         ;if no borrow after 17-bit subtraction
GOTO UOK46LL           ;skip remainder restoration.

ADDWF REMB0, F          ;restore higher byte of remainder. (w
;contains the value subtracted from it
;previously)
MOVF BARGB1, W          ;restore lower byte of remainder

UOK46LL

DECFSZ LOOPCOUNT, f     ;decrement counter
GOTO LOOPU2416         ;and repeat the loop if not zero.

RETURN

```
+
Thanks so much, this is a much simple routine,
but it did not work with me until I changed
the first line to :
```	movlw .24 ,
```
+

Questions:

Dear Piclist People:

Thanks to all for sharing your knowledge. I was wondering if some of you have had a problem like the one I describe below. Any help will be welcomed!
Iâ¬™m dealing with integer unsigned binary division using a PIC. I implemented 24/24 bit division and everything went ok. But when performing 24/16 bit division, something goes wrong.
The dividend (numerator) is a 24 bit constant, but the divisor (denominator) is a variable number. When this denominator takes a low value (but still 16 bit value), say 10700 i.e., the error in the result is quite a lot, and it becomes bigger as the difference between both operands does too. Is there a solution to this?
Thanks again for your help. Greetings!

• or 16 bits divided by 16 bits to 24 bits floating point? thanks!+
• anne_lauren_aspam at @spam@yahoo.com.ph asks: " How about dividing 24 bits by 16 bits resulting into a floating point? Thanks a lot! =)" +

• rickspam at @spam@silver-willows.co.uk
reference the LAST code segment.
Using a PIC18F4520, please note the code changes.
THANKS YOU all for saving me a lot of work.
```LOOPU2416
bcf	CARRY			; addition of code line
rlcf	BSR1_Larger24Lo,W 	; shift dividend left to move next bit to remainder
rlcf	BSR1_Larger24Mi,F
rlcf	BSR1_Larger24Hi,F
rlcf	BSR1_Remain16Lo,F	; shift carry (next dividend bit) into remainder
rlcf	BSR1_Remain16Hi,F
rlcf	BSR1_Larger24Lo,F	; finish shifting the dividend and save carry in
;  BSR1_Larger24Lo.0,
; since remainder can be 17 bit long in some cases
; (e.g. 0x800000/0xFFFF). This bit will also serve
; as the next result bit.

```

I apologise for spiling the convention in MY labels, but you can work backwards from the origonal code.
Rick

• rickspam at @spam@silver-willows.co.uk
Sorry, I forgot...
Also, for PIC184520...
replace SKPNC with btfsc CARRY
```;	SKPNC	 	;if no borrow after 16 bit subtraction
btfsc CARRY	; if no borrow after 16 bit subtraction
```
+

 file: /Techref/microchip/math/div/24by16.htm, 12KB, , updated: 2021/6/1 09:34, local time: 2024/9/18 20:29, TOP NEW HELP FIND:  18.205.56.209:LOG IN

 ©2024 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 Math Divide 24 bits by 16

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"

 PICList 2024 contributors: o List host: MIT, Site host massmind.org, Top posters @none found - 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.

.