Searching \ for '[[]MATH]' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/method/math.htm?key=math
Search entire site for: 'MATH]'.

No exact or substring matches. trying for part
PICList Thread
'[PIC]: [MATH] x^y routine implementation'
2000\09\27@130355 by D. Schouten

picon face
Hi All,


I'm in desparate need of a routine that calculates :

X raised to the power of Y (like the pow(x,y) function in C++)

where 0 < X < 1  (in a 0.16 fixed point notation)

and Y = 1.00 to 1.50 (in a 1.7 fixed point notation)

for a PIC16C73B.

I have about 2K of code-space and about 5000 clock-cycles available. I
already have implemented 8*8, 16*16, 24*16, 16/16, 32/16, 32-bit shift
left and 32-bit shift right routines (all unsigned) routines that can
be used if necessary.

I can't find such a routine on the web and the microchip application
note doesn't bring me any further since they don't have the
implementation for the 16Cxx series and besides that, they use 32-bit
precision wich is too high for my application.

I'm looking forward to any reply.

Thanks!

Daniel...

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use spam_OUTlistservTakeThisOuTspammitvma.mit.edu?body=SET%20PICList%20DIGEST


2000\09\28@041709 by Nikolai Golovchenko

flavicon
face
Hi Dan,

Try the logarithm ruler approach.

  z = x^y
log2 z = log2 x^y
log2 z = y * log2 x

  z = 2^(y*log2(x))
  ================

You have a couple of options to calculate that expression:

1) approximate calculation of log2 and 2^x with a small table
and linear approximation (probably just 16-32 entry table
would give a less than 0.5% error).

That would take under 1000 cycles and about 500 words.

See http://www.dattalo.com for an 8 bit log routine. Exp routine is
just the log routine reversed.

2) Using CORDIC method for log2 and 2^x. This is probably a
more precise method, but will take ~5000 cycles and as much
words.


So, I guess, the way to go is the option 1.

Let's see...

x2=LOG2(X), 0 < X < 1, 0.16 notation
=====================================
Note that X should be greater than zero, because log2(0)=-Inf.
Actually zero x is the easiest case, because 0^y=0. (y!=0)

In our case, log2(x) is in the range from -16 to -2.2e-5.
So we can use 6.10 notation (to reserve one bit for
multiplication by y) with implicit sign (it's always
negative) for log result.

To find the integer part of log, we rotate x left until
carry is set. The number of rotations is the approximated
log result (will give us an interpolation point).

log2
       clrf x2hi
log2loop
       clrc
       rlf xl, f
       rlf xh, f
       incf x2hi, f
       skpc
        goto log2loop
;x2hi contains approximated log (integer part + error)
       clrc            ;normalize x2
       rlf x2hi, f     ;for 6.10 notation
       rlf x2hi, f     ;
       clrf x2lo       ;clear lower byte

Then we use 4 higher bits of the rotated x and get a
fraction number from a table of log2(0.5)-log2(0.5:0.5/16:1),
that is a table of values that we add to the already found
integer part (note they are negative, so we can use
subtraction instead).

Columns 1 through 4
                 0  -0.08746284125034  -0.16992500144231  -0.24792751344359
 Columns 5 through 8   -0.32192809488736  -0.39231742277876  -0.45943161863730  -0.52356195605701
 Columns 9 through 12   -0.58496250072116  -0.64385618977472  -0.70043971814109  -0.75488750216347
 Columns 13 through 16   -0.80735492205760  -0.85798099512757  -0.90689059560852  -0.95419631038688
 Column 17   -1.00000000000000

Multiplied by -1024 and rounded (10 bits):
» round(-1024*(log2(0.5)-log2(0.5:0.5/16:1)))
ans =
 Columns 1 through 6            0          90         174         254         330         402
 Columns 7 through 12          470         536         599         659         717         773
 Columns 13 through 17          827         879         929         977        1024
(note, the table should have 16+1 entries!)
        ;prepare the index, i.e. shift xh right 3 times (4 bit index
;shifted left once)
       rrf xh, w
       movwf index
       rrf index, f
       rrf index, w
       andlw 0x1E
       movwf index
       call log2_table ;read the table entry to temphi:templo
;subtract it from current x2
       movf templo, w
       subwf x2lo, f
       movf temphi, w
       skpc
        incfsz temphi, w
         subwf x2hi, f
;read next point
       incf index, f
       incf index, f
       call log2_table ;read the table entry to temphi:templo
;find the difference with the previous point
       movf x2lo, w
       addwf templo, f
       movf x2hi, w
       skpnc
        incf x2hi, w
       addwf temphi, w
;leave only two lsb's of temphi (difference is 10 bit long)
       andlw 0x03
       movwf temphi
;now the difference is in temp
;multiply it by next 8 bits of the rotated x and divide by
;2^8=256

;shift xhi:xlo left by 4 bits to get 8 bits of the multiplier
;in xh. (xl is garbage)
       swapf   xhi, w
       andlw   0xF0
       movwf   xhi
       swapf   xlo, w
       andlw   0x0F
       iorwf   xhi, f
;we will simultaneously multiply and subtract from x2
       clrf xlo        ;use xlo as a temp
       movlw 8
       movwf index     ;use index as a counter
log2loop_mul
       rlf xhi, f      ;shift next multiplier bit to carry
       bnc log2loop_mul2 ;skip if no carry

       movf templo, w  ;subtract temp from x2hi:x2lo:xlo
       subwf xlo, f
       movf temphi, w
       skpc
        incfsz temphi, w
         subwf x2lo, f
       skpc
        decf x2hi, f

log2loop_mul2
       rrf x2hi, f     ;x2hi becomes garbage, but we'll
                       ;overwrite it
       rrf x2lo, f
       rrf xlo, f
       decfsz index, f
        goto log2loop_mul
;multiply x2 by 256 and overwrite x2hi to compensate 8 right
;rotations of x2 during the multiplication above
       movf x2lo, w
       movwf x2hi
       movf xlo, w
       movwf x2lo
;now x2 contains log2(x)!
       I didn't debug that, but I hope it helps. Please consider
publishing your results for us. :)

Nikolai




Post piclist\2000\09\27\130355a
[PIC]: [MATH] x^y routine implementation By: D. Schouten .
Hi All,


I'm in desparate need of a routine that calculates :

X raised to the power of Y (like the pow(x,y) function in C++)

where 0 < X < 1  (in a 0.16 fixed point notation)

and Y = 1.00 to 1.50 (in a 1.7 fixed point notation)

for a PIC16C73B.

I have about 2K of code-space and about 5000 clock-cycles available. I
already have implemented 8*8, 16*16, 24*16, 16/16, 32/16, 32-bit shift
left and 32-bit shift right routines (all unsigned) routines that can
be used if necessary.

I can't find such a routine on the web and the microchip application
note doesn't bring me any further since they don't have the
implementation for the 16Cxx series and besides that, they use 32-bit
precision wich is too high for my application.

I'm looking forward to any reply.

Thanks!

Daniel...

--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
use .....listservKILLspamspam@spam@mitvma.mit.edu?body=SET%20PICList%20DIGEST

--
http://www.piclist.com hint: To leave the PICList
piclist-unsubscribe-requestspamKILLspammitvma.mit.edu


2000\09\28@075821 by Nikolai Golovchenko

flavicon
face
I found some time to debug the log2 routine. It actually
works! Error is very small, less than 0.05%.

The whole x^y thing should take about 319*2+160 ~= 800
cycles and 105*2+20=220 words. Not so bad :)

 Nikolai

;************************************************
; LOG2 routine for fixed point unsigned
; 16 bit values in 0.16 notation
;
; Input: xhi:xlo unsigned Q0.16 (modified)
; Output: x2hi:x2lo unsigned Q6.10 (implicit minus)
; Temporary: index, templo, temphi
;
; Maximum error: 0.05%
;
; Size: 105 words
; Time: min 2+1+7*1 -1+10+18*2+8+17+10*8-1+4+2=165
;       max 2+1+7*15-1+10+18*2+8+17+17*8-1+4+2=319
;
; Note: Zero input is illegal! Will result in
;       infinite loop.
;
; 28 Sep 2000 by Nikolai Golovchenko
;************************************************
log2
       clrf x2hi
log2loop
       clrc
       rlf xlo, f
       rlf xhi, f
       incf x2hi, f
       skpc
        goto log2loop
;x2hi contains approximated log (integer part + error)
       clrc            ;normalize x2
       rlf x2hi, f     ;for 6.10 notation
       rlf x2hi, f     ;
       clrf x2lo       ;clear lower byte

;prepare the index, i.e. shift xh right 3 times (4 bit index
;shifted left once)
       rrf xhi, w
       movwf index
       rrf index, f
       rrf index, w
       andlw 0x1E
       movwf index
       call log2_table ;read the table entry to temphi:templo
;subtract it from current x2
       movf templo, w
       subwf x2lo, f
       movf temphi, w
       skpc
        incfsz temphi, w
         subwf x2hi, f
;read next point
       incf index, f
       incf index, f
       call log2_table ;read the table entry to temphi:templo
;find the difference with the previous point
       movf x2lo, w
       addwf templo, f
       movf x2hi, w
       skpnc
        incf x2hi, w
       addwf temphi, w
;leave only two lsb's of temphi (difference is 10 bit long)
       andlw 0x03
       movwf temphi
;now the difference is in temp
;multiply it by next 8 bits of the rotated x and divide by
;2^8=256

;shift xhi:xlo left by 4 bits to get 8 bits of the multiplier
;in xh. (xlo is garbage)
       swapf   xhi, w
       andlw   0xF0
       movwf   xhi
       swapf   xlo, w
       andlw   0x0F
       iorwf   xhi, f
;we will simultaneously multiply and subtract from x2
       clrf xlo        ;use xlo as a temp
       movlw 8
       movwf index     ;use index as a counter
log2loop_mul
       rrf xhi, f      ;shift next multiplier bit to carry
       bnc log2loop_mul2 ;skip if no carry

       movf templo, w  ;subtract temp from x2hi:x2lo:xlo
       subwf xlo, f
       movf temphi, w
       skpc
        incfsz temphi, w
         subwf x2lo, f
       skpc
        decf x2hi, f

log2loop_mul2
       rrf x2hi, f     ;x2hi becomes garbage, but we'll
                       ;overwrite it
       rrf x2lo, f
       rrf xlo, f
       decfsz index, f
        goto log2loop_mul
;multiply x2 by 256 and overwrite x2hi to compensate 8 right
;rotations of x2 during the multiplication above
       movf x2lo, w
       movwf x2hi
       movf xlo, w
       movwf x2lo
;now x2 contains log2(x)!
       return

log2_table
       movf index, w
       call log2tableStart
       movwf templo
       incf index, w
       call log2tableStart
       movwf temphi
       return

log2tableStart
       addwf PCL, f
       DT   0 & 0xFF,   0 >> 8,  90 & 0xFF,  90 >> 8
       DT 174 & 0xFF, 174 >> 8, 254 & 0xFF, 254 >> 8
       DT 330 & 0xFF, 330 >> 8, 402 & 0xFF, 402 >> 8
       DT 470 & 0xFF, 470 >> 8, 536 & 0xFF, 536 >> 8
       DT 599 & 0xFF, 599 >> 8, 659 & 0xFF, 659 >> 8
       DT 717 & 0xFF, 717 >> 8, 773 & 0xFF, 773 >> 8
       DT 827 & 0xFF, 827 >> 8, 879 & 0xFF, 879 >> 8
       DT 929 & 0xFF, 929 >> 8, 977 & 0xFF, 977 >> 8
IF (($ - 1) >> 8) - ((log2tableStart + 1) >> 8) != 0
       error 'log2 table crossed 8-bit boundary'
ENDIF
;************************************************

--
http://www.piclist.com hint: To leave the PICList
.....piclist-unsubscribe-requestKILLspamspam.....mitvma.mit.edu


2000\09\28@080926 by Nikolai Golovchenko

flavicon
face
Oh s**t, the table should have 17 entries! Or a roll-over...
Corrected routine below.



----------------------------------------------------

I found some time to debug the log2 routine. It actually
works! Error is very small, less than 0.05%.

The whole x^y thing should take about 319*2+160 ~= 800
cycles and 105*2+20=220 words. Not so bad :)

 Nikolai

;************************************************
; LOG2 routine for fixed point unsigned
; 16 bit values in 0.16 notation
;
; Input: xhi:xlo unsigned Q0.16 (modified)
; Output: x2hi:x2lo unsigned Q6.10 (implicit minus)
; Temporary: index, templo, temphi
;
; Maximum error: 0.05%
;
; Size: 105 words
; Time: min 2+1+7*1 -1+10+20*2+8+17+10*8-1+4+2=169
;       max 2+1+7*15-1+10+20*2+8+17+17*8-1+4+2=323
;
; Note: Zero input is illegal! Will result in
;       infinite loop.
;
; 28 Sep 2000 by Nikolai Golovchenko
;************************************************
log2
       clrf x2hi
log2loop
       clrc
       rlf xlo, f
       rlf xhi, f
       incf x2hi, f
       skpc
        goto log2loop
;x2hi contains approximated log (integer part + error)
       clrc            ;normalize x2
       rlf x2hi, f     ;for 6.10 notation
       rlf x2hi, f     ;
       clrf x2lo       ;clear lower byte

;prepare the index, i.e. shift xh right 3 times (4 bit index
;shifted left once)
       rrf xhi, w
       movwf index
       rrf index, f
       rrf index, w
       andlw 0x1E
       movwf index
       call log2_table ;read the table entry to temphi:templo
;subtract it from current x2
       movf templo, w
       subwf x2lo, f
       movf temphi, w
       skpc
        incfsz temphi, w
         subwf x2hi, f
;read next point
       incf index, f
       incf index, f
       call log2_table ;read the table entry to temphi:templo
;find the difference with the previous point
       movf x2lo, w
       addwf templo, f
       movf x2hi, w
       skpnc
        incf x2hi, w
       addwf temphi, w
;leave only two lsb's of temphi (difference is 10 bit long)
       andlw 0x03
       movwf temphi
;now the difference is in temp
;multiply it by next 8 bits of the rotated x and divide by
;2^8=256

;shift xhi:xlo left by 4 bits to get 8 bits of the multiplier
;in xh. (xlo is garbage)
       swapf   xhi, w
       andlw   0xF0
       movwf   xhi
       swapf   xlo, w
       andlw   0x0F
       iorwf   xhi, f
;we will simultaneously multiply and subtract from x2
       clrf xlo        ;use xlo as a temp
       movlw 8
       movwf index     ;use index as a counter
log2loop_mul
       rrf xhi, f      ;shift next multiplier bit to carry
       bnc log2loop_mul2 ;skip if no carry

       movf templo, w  ;subtract temp from x2hi:x2lo:xlo
       subwf xlo, f
       movf temphi, w
       skpc
        incfsz temphi, w
         subwf x2lo, f
       skpc
        decf x2hi, f

log2loop_mul2
       rrf x2hi, f     ;x2hi becomes garbage, but we'll
                       ;overwrite it
       rrf x2lo, f
       rrf xlo, f
       decfsz index, f
        goto log2loop_mul
;multiply x2 by 256 and overwrite x2hi to compensate 8 right
;rotations of x2 during the multiplication above
       movf x2lo, w
       movwf x2hi
       movf xlo, w
       movwf x2lo
;now x2 contains log2(x)!
       return

log2_table
       movf index, w
       andlw 0x1F
       call log2tableStart
       movwf templo
       incf index, w
       andlw 0x1F
       call log2tableStart
       movwf temphi
       return

log2tableStart
       addwf PCL, f
       DT   0 & 0xFF,   0 >> 8,  90 & 0xFF,  90 >> 8
       DT 174 & 0xFF, 174 >> 8, 254 & 0xFF, 254 >> 8
       DT 330 & 0xFF, 330 >> 8, 402 & 0xFF, 402 >> 8
       DT 470 & 0xFF, 470 >> 8, 536 & 0xFF, 536 >> 8
       DT 599 & 0xFF, 599 >> 8, 659 & 0xFF, 659 >> 8
       DT 717 & 0xFF, 717 >> 8, 773 & 0xFF, 773 >> 8
       DT 827 & 0xFF, 827 >> 8, 879 & 0xFF, 879 >> 8
       DT 929 & 0xFF, 929 >> 8, 977 & 0xFF, 977 >> 8
IF (($ - 1) >> 8) - ((log2tableStart + 1) >> 8) != 0
       error 'log2 table crossed 8-bit boundary'
ENDIF
;************************************************

--
http://www.piclist.com hint: To leave the PICList
EraseMEpiclist-unsubscribe-requestspam_OUTspamTakeThisOuTmitvma.mit.edu


2000\09\29@003352 by Scott Dattalo
face
flavicon
face
On Wed, 27 Sep 2000, D. Schouten wrote:

> Hi All,
>
>
> I'm in desparate need of a routine that calculates :
>
>  X raised to the power of Y (like the pow(x,y) function in C++)
>
>  where 0 < X < 1  (in a 0.16 fixed point notation)
>
>  and Y = 1.00 to 1.50 (in a 1.7 fixed point notation)
>
> for a PIC16C73B.


In addition to the methods mentioned by Nikolai, there is also Feynman's Power
Algorithm. I haven't implemented this with pic code, but did test it out in
basic (a long time ago). The algorithm is described in a homework problem in
chapter 1 of Knuth's "The Art of Computer Programming: Fundamental Algorithms".
BTW, if you don't have the three volumes of Knuth's books, then get them!

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
"[PIC]:" PIC only "[EE]:" engineering "[OT]:" off topic "[AD]:" ad's


2000\09\29@085829 by daan xs4all

picon face
Scott,

thanks for the Knuth's books tip! I will check these out.

I'm currently working on the algorithm. I will keep you
up to date when I've made any progress.

Daniel...


{Original Message removed}

2000\09\29@100606 by M. Adam Davis

flavicon
face
I wish I could find a cheap source for them!  (or the original TEX files...  I
think he should release all of them to the public domain, though I suspect some
publisher still holds the rights...)

He is still, apparently, working on the fourth volume though, so when(if) it
comes out I imagine there will be a reprinting of all of them.

My local school library has the first one, but not the other two  <sigh>, but
occasionally you'll see them on ebay and at other places.

-Adam

Scott Dattalo wrote:
{Quote hidden}

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
"[PIC]:" PIC only "[EE]:" engineering "[OT]:" off topic "[AD]:" ad's


2000\09\29@100809 by Robert A. LaBudde

flavicon
face
At 02:55 PM 9/29/00 +0100, Daniel wrote:
>Scott,
>
>thanks for the Knuth's books tip! I will check these out.
>
>I'm currently working on the algorithm. I will keep you
>up to date when I've made any progress.

The standard method for x^y (x, y real) in high-level languages is via
scaling to a number between 0 and 1, then using a rational Chebyshev
expansions to calculate exp(a) and log(b). (x^y = e^(y ln x)

If x and y are integer, or y is integer, much simpler methods exist.

================================================================
Robert A. LaBudde, PhD, PAS, Dpl. ACAFS  e-mail: ralspamspam_OUTlcfltd.com
Least Cost Formulations, Ltd.            URL: http://lcfltd.com/
824 Timberlake Drive                     Tel: 757-467-0954
Virginia Beach, VA 23464-3239            Fax: 757-467-2947

"Vere scire est per causas scire"
================================================================

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
"[PIC]:" PIC only "[EE]:" engineering "[OT]:" off topic "[AD]:" ad's


'[PIC]: [MATH]: Power function, part 2'
2000\09\29@175856 by D. Schouten

picon face
Hi List / Nikolai,

Thanks again for the log2() function Nikolai.

I've implemented it in my program and it works perfectly now (took a
little time to get it work because of a really stupid mistake of me).
I have also implemented the multiplication by y (compared to the log2
function, this is a piece of cake of course), so the the
power-function is now finished till :

y * log2(x)

where the result is in an unsigned Q6.10 (implicit minus) notation.

Now I only have to take care of the exp() function. But the problem is
that I'm not a math-wizard like Nikolai. So I would really appreciate
it if you could help me out with that routine also. The output of the
exp() function has to be in the unsigned Q0.16 format again.

Again thanks a lot.

Daniel...

--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
"[PIC]:" PIC only "[EE]:" engineering "[OT]:" off topic "[AD]:" ad's


2000\09\30@043514 by Nikolai Golovchenko

flavicon
face
part 1 6460 bytes content-type:text/plain; charset=ISO-8859-1 (decoded quoted-printable)

Hi Daniel,

Well, let's calculate y=2^x! x is Q6.10 notation (always
negative with implicit sign). Output y has Q0.16 notation
(always less then 1). Therefore x should not be zero (2^0 =
1).

y is in the range from 0.9993 (x = -1/1024) to 5e-20 (x
= -64 + 1/1024). Okay....

y=2^x

y=2^-(32*x.15+16*x.14+...1*x.10 + 0.5*x.9+0.25*x.8+...)
   \========================/   \===================/
         x_int                         x_frac

x_int = 0:1:63
x_frac = 0:1/1024:(1-1/1024)

y=2^-(x_int+x_frac)

y=2^(-x_int) * 2^(-x_frac)

y= (2^(-x_frac)) >> x_int
=========================

So we first find 2^-x_frac using a table and then shift the
result right x_int times.

First we should convert the fraction part through a table to
a new fraction part. 2^(-0..-1) = 0.5..1

; y = 2^x2
;Input: x2hi:x2lo
;Output: yhi:ylo

;Form table index from 4 higher bits of x2 fraction part
       rlf x2lo, f
       rlf x2ho, w
       movwf index
       rlf x2lo, w
       rlf index, f
;here middle 6 bits of x2lo contain multiplier for linear
;interpolation, and index has 4 lower bits of table pointer
       rlf index, w    ;multiply index by 2 for 16 bit
                       ;entries addressing
       andlw 0x1E      ;and clear lsb and higher bits
       movwf index
;Read first point to temphi:templo
       call exp2_table

;clear result and subtract the first point from it
       clrf yhi
       clrf ylo
       movf templo, w
       subwf ylo, f
       movf temphi, w
       skpc
        incfsz temphi, w
         subwf yhi, f
;Read next point to temphi:templo
       incf index, f
       incf index, f
       call exp2_table
;find difference with previous point to temphi:templo
       movf ylo, w
       addwf templo, f
       movf yhi, w
       skpnc
        incfsz yhi, w
         addwf temphi, f
;multiply the difference by the next 6 fraction bits in
;x2lo and divide by 64. Then subtract it from the current
;result in yhi:ylo
       movlw 6
       movwf index     ;use index as a loop counter
       rrf x2lo, f     ;align the 6 bits to the lsb

       clrf temp       ;we will use another temp
                       ;for mul purposes

       rrf yhi, f      ;rotate y right 2 times
       rrf ylo, f      ;to make easy multiplication.
       rrf temp, f     ;lower bits will go to temp
       rrf yhi, f
       rrf ylo, f
       rrf temp, f
exp2loop
       rrf x2lo, f      ;get next multiplier bit
       bnc exp2loopnext ;skip subtraction if carry is clear

       movf templo, w
       subwf temp, f
       movf temphi, w
       skpc
        incfsz temphi, w
         subwf ylo, f
       skpc
        decf yhi, f

exp2loopnext

       rrf yhi, f
       rrf ylo, f
       rrf temp, f
       decfsz index, f
        goto exp2loop
;shift the result 8 bits left
       movf ylo, w
       movwf yhi
       movf temp, w
       movwf ylo

;Now we will shift y right the number of times
;equal to the integer part of x2
       clrc            ;align integer bits
       rrf x2hi, f     ;to lsb
       clrc
       rrf x2hi, f

       test x2hi
       skpnz
        return         ;done
exp2loop2
       clrc
       rrf y2hi, f
       rrf y2lo, f
       decfsz x2hi, f
        goto exp2loop2
       return          ;done

Now we need to calculate the table...
1-2.^(0:-1/16:-1)
ans =
 Columns 1 through 4                   0   0.04239671930143   0.08299595679533   0.12187391981335
 Columns 5 through 8    0.15910358474629   0.19475483402537   0.22889458729603   0.26158692703025
 Columns 9 through 12    0.29289321881345   0.32287222653155   0.35158022267450   0.37907109396326
 Columns 13 through 16    0.40539644249864   0.43060568262165   0.45474613366737   0.47786310878629
 Column 17    0.50000000000000

Multiplied by 65536 and rounded
round(65536*(1-2.^(0:-1/16:-1)))
ans =
 Columns 1 through 6            0        2779        5439        7987       10427       12763
 Columns 7 through 12        15001       17143       19195       21160       23041       24843
 Columns 13 through 17        26568       28220       29802       31317       32768

So, the table would be:

exp2_table
       movf index, w
       call exp2tableStart
       movwf templo
       incf index, w
       call exp2tableStart
       movwf temphi
       return

exp2tableStart
       addwf PCL, f
       DT     0 & 0xFF,     0 >> 8,  2779 & 0xFF,  2779 >> 8
       DT  5439 & 0xFF,  5439 >> 8,  7987 & 0xFF,  7987 >> 8
       DT 10427 & 0xFF, 10427 >> 8, 12763 & 0xFF, 12763 >> 8
       DT 15001 & 0xFF, 15001 >> 8, 17143 & 0xFF, 17143 >> 8
       DT 19195 & 0xFF, 19195 >> 8, 21160 & 0xFF, 21160 >> 8
       DT 23041 & 0xFF, 23041 >> 8, 24843 & 0xFF, 24843 >> 8
       DT 26568 & 0xFF, 26568 >> 8, 28220 & 0xFF, 28220 >> 8
       DT 29802 & 0xFF, 29802 >> 8, 31317 & 0xFF, 31317 >> 8
       DT 32768 & 0xFF, 32768 >> 8
IF (($ - 1) >> 8) - ((exp2tableStart + 1) >> 8) != 0
       error 'exp2 table crossed 8-bit boundary'
ENDIF

And the cleaned up version is attached... Yeah, this one was
harder and not really the reverse of log!

Don't forget to check x and y for zero in x^y.

Hope it works for you :)
 Nikolai

---- Original Message ----
From: D. Schouten <@spam@danielsKILLspamspamxs4all.nl>
Sent: Saturday, September 30, 2000 0:56:03
 To: Nikolai Golovchenko
Subj: [PIC]: [MATH]: Power function, part 2

{Quote hidden}


part 2 8615 bytes content-type:application/octet-stream; name="log2exp2.asm" (decode)

part 3 144 bytes
--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics



'[PIC]: [MATH]: Power function, part 2'
2000\10\03@131101 by D. Schouten
picon face
Hi List / Nikolai,

Thanks for the Exp2 routine Nikolai!

I've also implemented this last piece of the power function. It works
perfectly now but it took a little time to debug. I found two little
bugs in the Exp2 routine in the log2exp2.asm attachment:

1.) the code :

       tstf x2hi
       skpnz
        return         ;done

has to be placed UNDER :

       clrc            ;align integer bits
       rrf x2hi, f     ;to lsb
       clrc
       rrf x2hi, f

instead of above. This is done right in the explanation posted on the
list but wrong in the attached log2exp2.asm.

2.) in the piece of code :

       movlw 17     ;limit shifts number to 16 maximum
       subwf x2hi, w
       movlw 16
       skpc
        movwf x2hi

the instruction :

       skpc

has to be changed in :

       skpnc

to limit shifts number to 16 like Nikolai says in the comment.


Again, thank you very much Nikolai. The routine is not only very
accurate, it's also efficient. The whole power function takes less
then 1000 cycles to calculate and uses less then 300 words of
codespace. WOW!

Again thanks!

Bye,

Daniel...

--
http://www.piclist.com hint: To leave the PICList
KILLspampiclist-unsubscribe-requestKILLspamspammitvma.mit.edu


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