Searching \ for '[PIC] A math problem?' in subject line. ()
Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/math/index.htm?key=math
Search entire site for: 'A math problem?'.

Exact match. Not showing close matches.
'[PIC] A math problem?'
1996\05\06@152224 by

I need to solve this simple equation using a 16C74:

ans = (X*Y)/Z

ans, X, Y, and Z are all one byte variables (0-255)
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 non-interger number, but I need a "close"
approximation so the ans will fit into one byte.  I would rather not deal
with any 16-bit 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

Zach
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 (0-255)
> 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 non-interger number, but I need a "close"
> approximation so the ans will fit into one byte.  I would rather not deal
> with any 16-bit 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 "long-wise" as two 8 / 8 operations with a carry.

Rick Miller
<rdmillerexecpc.com>
Xaq <xaqINDIRECT.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 (0-255)
>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
rrf     accHI, f
rrf     accLO, f
decfsz  count, f
goto    loop

retlw   0

--
Bob Fehrenbach    Wauwatosa, WI     bfehrenbexecpc.com

More... (looser matching)
- Last day of these posts
- In 1996 , 1997 only
- Today
- New search...