-----Mensagem Original----- De: Andy David Para: Enviada em: Quinta-feira, 28 de Outubro de 1999 09:40 Assunto: FW: fw06@pop.dial.pipex.com r. unknown " 16-BIT DIVISION" Luis, I can't post directly to the PIClist, can you forward this to the list for me, pls? Best regards, - Andy. --------------------------------------------------------- Andrew David, Software Manager, Ultronics Ltd, Cheltenham akdavid@ultronics.co.uk http://www.ultronics.com > -----Original Message----- > From: Andy David > Sent: Thursday, October 28, 1999 12:11 PM > To: 'pic microcontroller discussion list' > Subject: RE: fw06@pop.dial.pipex.com r. unknown " 16-BIT > DIVISION" > > >I am looking for a routine in ASM that make a division of a > 16-bit binary > >number for 5 . > >For example. > >015Eh / 05 = 046h > > > >So my 16-bit binary number will never be larger than 03DEH, > with this I will > >need only 1 byte for the result. > > Luis, > > instead of dividing by 5, how about multiplying by 0.2 (1/5)? > > i.e., 0x015e* 0x00cd >> 0x000a > > which will probably execute more quickly (unless someone else like > Dmitry or Bob Fehrenbach) knows a good algorithm that specifically > gives x/5) - but beware that 0x00cd >> 0x000a (205/1024) gives an > approximation to 0x015e/5, but it's pretty close - it gives the > correct answer for 0 to 0x03de, but can be 1 out for larger numbers > (I've just used a spreadsheet to test the results). > > Now I come to think of it, I'm sure Andy Warren posted a divide-by-5 > algorithm a few years ago (1996, I think) that was quick, it should be > in the archives at: http://www.iversoft.com/piclist/ > > > - Andy. > > --------------------------------------------------------- > Andrew David, Software Manager, Ultronics Ltd, Cheltenham > akdavid@ultronics.co.uk http://www.ultronics.com > > I don't have a 16 by 8 division handy, but here's a 16 by 8 multiply > and a right shifter, both for 14-bit core PICs. I've just thrown this > together and I haven't assembled it, but it shows use of multiplying > by 1/5. > > ;===================================================================== > = > > CBLOCK > ACCaHI > ACCaLO > ACCbHI > ACCbLO > ACCcHI > ACCcLO > ACCdHI > ACCdLO > ENDC > TestNumber equ 0x0153 ; Original test number = 0x0153 DivGain equ 0xcd ; Div by 5 = multiply by 1/5 DivScale equ 0x0a ; ... which is close to 205/2^10 > movlw HIGH TestNumber ; Test number into ACCaHI:ACCaLO > movwf ACCaHI ; > movlw LOW TestNumber ; > movwf ACCaLO ; > movlw DivGain ; x/5 is approximated by: > movwf ACCbHI ; ... x * 205 / 2^10 > call mpy8_16 ; > > movlw DivScale ; Right shift result of > multiplication > movwf ACCdLO ; ... 10 bits to > complete calculation. > call scldn24 ; Final result in ACCcLO:ACCdHI > > ;===================================================================== > = > > > ;===================================================================== > = > ; mpy8_16 > ; > ; Multiplies an 8 bit number by a 16 bit number. > ; > ; Ins: 8 bit input in ACCbHI > ; 16 bit input in ACCaHI:ACCaLO > ; > ; Outs: 24 bit result in ACCcHI:ACCcLO:ACCdHI > ; > ; Uses: ACCdLO > ;===================================================================== > = > > mpy8_16:movlw 8 ; Temp1h used as a loop counter, set > to > movwf ACCdLO ; ... 8 loops. > clrf ACCcHI ; ACCcHI:ACCcLO:ACCdHI is the result > clrf ACCcLO ; ... accumulator, this must be set to > > clrf ACCdHI ; ... 0 at the start. > > m8_16loop:rrf ACCbHI, F ; > btfss STATUS,C ; > goto noadd ; > > movf ACCaLO,w ; Add the multiplier to the partial > product. > addwf ACCcLO,f ; ... Note that this addition can be > made > movf ACCaHI,w ; ... 1 cycle shorter if the carry out > of > btfsc STATUS,C ; ... the high byte is not important. > incfsz ACCcHI,f ; > addwf ACCcHI,w ; > movwf ACCcHI ; > > noadd: bcf STATUS,C > rrf ACCcHI,f ; shift partial result right > rrf ACCcLO,f ; > rrf ACCdHI,f ; > > decfsz ACCdLO, F ; > goto m8_16loop > > return > > ;===================================================================== > ======== > ; scldn24 > ; > ; 24 bit right shift routine - right shifts ACCcHI:ACCcLO:ACCdHI > by > ; number of bits given in ACCdLO. > ; > ;===================================================================== > ======== > > scldn24:incf ACCdLO,f ; add 1 - to cope with sc of 0 > s24strt:decfsz ACCdLO,f ; > goto shft24 ; > > return > > shft24: bcf STATUS,C > rrf ACCcHI,f ; rotate bytes in turn through carry. > rrf ACCcLO,f ; > rrf ACCdHI,f ; > > goto s24strt ;