from Nikolai Golovchenko
;Division of 16bit by 8 bit with a result in Q16.16 form ; ; X_Int.X_Frac = X_Int / Y ; ; RAM - 6 bytes (1 temp): ; X_Int = X_IntH:X_IntL 16 bit input/ output integer part ; X_Frac = X_FracH:X_FracL 16 bit output fractional part ; Y divisor / temporary ; Counter counter ; ; Size = 39 instructions ; Execution time = 6+16*14-1+3+16*14-1+3+2(return) ; = 460 instruction cycles ; ; 8-July-2000 by Nikolai Golovchenko ; 16-February-2001 fixed, reduced execution time and temporaries Div16by8to16_16 clrf X_FracL clrf X_FracH movlw 16 movwf Counter movf Y, w ;keep Y value in accumulator clrf Y ;and use Y register as temporary ;Find integer part Div16by8to16_16a rlf X_IntL, f ;shift next msb into temporary rlf X_IntH, f rlf Y, f rlf Counter, f ;carry has 9th bit of temporary ;copy carry to counter subwf Y, f ;substract Y (in w) from temporary skpnc ;if no borrow, set Counter.0 bsf Counter, 0 btfss Counter, 0 ;if Counter.0 clear (borrow) restore temporary addwf Y, f clrc ;restore counter rrf Counter, f ;at this point carry is the next bit of result decfsz Counter, f ;repeat 16 times to find integer part goto Div16by8to16_16a ;shift last integer bit rlf X_IntL, f rlf X_IntH, f ;Find fractional part bsf Counter, 4 ;Counter = 16 Div16by8to16_16b ;Shift zero bit into temporary rlf X_FracL, f rlf X_FracH, f rlf Y, f rlf Counter, f ;carry has 9th bit of temporary ;copy carry to counter subwf Y, f ;substract Y(in w) from temporary skpnc ;if no borrow, set Counter.0 bsf Counter, 0 btfss Counter, 0 ;if Counter.0 clear (borrow) restore temporary addwf Y, f clrc ;restore counter rrf Counter, f decfsz Counter, f ;repeat 16 times goto Div16by8to16_16b ;shift last fractional bit rlf X_FracL, f rlf X_FracH, f movwf Y ;restore divisor return
Questions:
This code did not work as expected. I send you the whole code.+list p=16F84A ; list directive to define processor #include <p16F84a.inc> ; processor specific variable definitions __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_OFF & _XT_OSC ;***** VARIABLE DEFINITIONS ;w_temp EQU 0x0C ; variable used for context saving ;status_temp EQU 0x0D ; variable used for context saving ;********************************************************************** cblock 0x0C w_temp status_temp X_IntH X_IntL X_FracH X_FracL Counter Y endc ;********************************************************************** RESET_VECTOR CODE 0x0000 ; processor reset vector goto Start ; go to beginning of program ISR CODE 0x0004 ; interrupt vector location Interrupt: movwf w_temp ; save off current W register contents movf STATUS,w ; move status register into W register movwf status_temp ; save off contents of STATUS register ; Place ISR Here movf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt MAIN_PROGRAM CODE Start: ; Loading the divident and the divisor movlw .100 movwf X_IntL movlw .34 movwf Y Main Div16by8to16_16 clrf X_FracL clrf X_FracH movlw 16 movwf Counter movf Y, w ;keep Y value in accumulator clrf Y ;and use Y register as temporary ;Find integer part Div16by8to16_16a rlf X_IntL, f ;shift next msb into temporary rlf X_IntH, f rlf Y, f rlf Counter, f ;carry has 9th bit of temporary ;copy carry to counter subwf Y, f ;substract Y (in w) from temporary skpnc ;if no borrow, set Counter.0 bsf Counter, 0 btfss Counter, 0 ;if Counter.0 clear (borrow) restore temporary addwf Y, f clrc ;restore counter rrf Counter, f ;at this point carry is the next bit of result decfsz Counter, f ;repeat 16 times to find integer part goto Div16by8to16_16a ;shift last integer bit rlf X_IntL, f rlf X_IntH, f ;goto $ ;Find fractional part bsf Counter, 4 ;Counter = 16 Div16by8to16_16b ;Shift zero bit into temporary rlf X_FracL, f rlf X_FracH, f rlf Y, f rlf Counter, f ;carry has 9th bit of temporary ;copy carry to counter subwf Y, f ;substract Y(in w) from temporary skpnc ;if no borrow, set Counter.0 bsf Counter, 0 btfss Counter, 0 ;if Counter.0 clear (borrow) restore temporary addwf Y, f clrc ;restore counter rrf Counter, f decfsz Counter, f ;repeat 16 times goto Div16by8to16_16b ;shift last fractional bit rlf X_FracL, f rlf X_FracH, f movwf Y ;restore divisor ;return goto $ END ; directive 'end of program'
I've tried the 16bits by 8 bits with Q16.16 divide code running base on 16F873. The Integer seems to be ok however what answer should i expect from the fractional part. Is it a fractinal value or remainder
Nikolai Golovchenko answers:
You should expect the fractional part to be just that - the fractional part, it is not a remainder. This is a binary representation of fixed point numbers, where the highest bit (bit15) weight equals 1/2, bit14 = 1/4, bit13 = 1/8, ..., bit0 = 1/65536. A few examples: .0000 0000 0000 0000b = 0d .0000 0000 0000 0001b = 1/65536d ~= 0.00001526d .0000 0000 0000 0010b = 1/32768d ~= 0.00003052d .0000 0000 0000 0011b = 1/65536d + 1/32768d ~= 0.00004578d .0000 0000 0000 0100b = 1/16384d ... .1111 1111 1111 1111b = 1/65536d + 1/32768d + ... + 1/2d = = 65535 / 65536 ~= 0.9999847d You can convert it to decimal by simply dividing X_Frac by 65536. The full division result is: X_Int + X_Frac/65536 For example: X_Int = 103 Y = 2 Answer (X_Int/Y): X_Int = 51, X_Frac=32768. In binary: 0000 0000 0011 0011 . 1000 0000 0000 0000 \_____ X_Int______/ \_____ X_Frac ____/ Or, 32+16+2+1+1/2=51.5
file: /Techref/microchip/math/div/16by8lzf-ng.htm, 8KB, , updated: 2021/3/19 18:59, local time: 2023/6/1 19:26, owner: NG--944, |
©2023 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? <A HREF="http://www.piclist.com/techref/microchip/math/div/16by8lzf-ng.htm"> PIC Microcontoller Math Method Division 16 bits by 8 with result as fraction rather than remainder </A> |
Did you find what you needed? |
PICList 2023 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. |
Welcome to www.piclist.com! |
.