Exact match. Not showing close matches.
PICList
Thread
'[PIC] A math problem?'
1996\05\06@152224
by
Xaq
I need to solve this simple equation using a 16C74:
ans = (X*Y)/Z
ans, X, Y, and Z are all one byte variables (0255)
Z is ALWAYS greater than Y, but X can be ANY number except zero.
None of the numbers are ever zero.
I know this will usually produce a noninterger number, but I need a "close"
approximation so the ans will fit into one byte. I would rather not deal
with any 16bit numbers(or floating point routines), so multiplying X*Y
first would not work because it risks an overflow. Also, by doing Y/Z
first, will give a number less than one.
It also needs to be done in under a few hundred instruction cycles.
I have not had much experience with writing math routines in assembly so any
help would be appreciated
Thanks for your help,
Zach
1996\05\06@161425
by
rdmiller
On Mon, 6 May 1996, Xaq wrote:
> I need to solve this simple equation using a 16C74:
>
> ans = (X*Y)/Z
>
> ans, X, Y, and Z are all one byte variables (0255)
> Z is ALWAYS greater than Y, but X can be ANY number except zero.
> None of the numbers are ever zero.
>
> I know this will usually produce a noninterger number, but I need a "close"
> approximation so the ans will fit into one byte. I would rather not deal
> with any 16bit numbers(or floating point routines), so multiplying X*Y
> first would not work because it risks an overflow. Also, by doing Y/Z
> first, will give a number less than one.
I think your best bet would be to do the 8 x 8 multiply first, then do
the 16 / 8 division "longwise" as two 8 / 8 operations with a carry.
Rick Miller
<spam_OUTrdmillerTakeThisOuTexecpc.com>
1996\05\06@173356
by
Bob Fehrenbach

Xaq <.....xaqKILLspam@spam@INDIRECT.COM> wrote:
>I need to solve this simple equation using a 16C74:
>
> ans = (X*Y)/Z
>
>ans, X, Y, and Z are all one byte variables (0255)
>Z is ALWAYS greater than Y, but X can be ANY number except zero.
>None of the numbers are ever zero.
Zach,
Since Z > Y, the answer should always fit in one byte. You will,
however, need a two byte intermediate result. Try the following.
I think you will find the code reasonably compact.
movf X, w
movwf mulplr
movf Y, w
movwf mulcnd
call mpy ;> accHI:accLO
movf Z, w
call div8 ;Final result in accLO
;Divide 16 bits by 8 bits, 8 bit result.
;Conventional shift and subtract
;Result MUST fit in 8 bits, otherwise erroneous result.
;110 clock cycles.
;Source: Bob Fehrenbach
; accHI : accLO / dvsr > accLO, rem in accHI
div8:
movlw 8
movwf count
div_loop:
rlf accLO, f
rlf accHI, f
rlf temp, f ;save "borrow"
movf dvsr, w
subwf accHI,w
btfss temp, 0 ;Save result if borrow = 1
skpnc ;Else, save only if positive
movwf accHI
btfsc temp, 0 ;Make sure carry is a 1 if
rrf temp, f ;borrow = 1
decfsz count, f
goto div_loop
rlf accLO, f ;quotient in accLO
div_exit: ;remainder in accHI
return
;**************************************************************************
; 8x8 Multiply, 16 bit Result
;
; mulplr * mulcnd > accHI:accLO
; 71 clock cycles
; (From Microchip app note AN526)
;
mpy:
clrf accHI
clrf accLO
movlw 8
movwf count
movf mulcnd,w
bcf STATUS,C
loop
rrf mulplr, f
btfsc STATUS,C
addwf accHI, f
rrf accHI, f
rrf accLO, f
decfsz count, f
goto loop
retlw 0

Bob Fehrenbach Wauwatosa, WI bfehrenbKILLspamexecpc.com
More... (looser matching)
 Last day of these posts
 In 1996
, 1997 only
 Today
 New search...