please dont rip this site

PIC Microcontoller Math Method

2 ^ X 16 Bit 0.16 notation

by Nikolai Golovchenko debugged by Daniel Schouten [daniels at XS4ALL.NL]

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 below... 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.

#include <p16f84.inc>

	cblock 0x20
	xhi, xlo
	templo, temphi, temp
	index
	x2hi, x2lo
	endc


#define tval 65300

	movlw tval & 0xFF
	movwf xlo
	movlw tval >> 8
	movwf xhi
	call log2
	nop
	call exp2
	nop
	

;************************************************
; EXP2 routine for fixed point unsigned
; 16 bit values in 6.10 notation (implicit minus)
;
; Input: x2hi:x2lo unsigned Q6.10 (implicit minus)
; Output: xhi:xlo unsigned Q0.16
; Temporary: index, templo, temphi, temp
;
; Maximum error: 0.025% (for x2 < 1)
;
; Size:  121 words
; Time: min 2+8+18*2+10+16+10*6-1+6+2=139
;       max 2+8+18*2+10+16+17*6-1+6+1+14+6*16-1+2=291
;
; Note: Zero input is illegal! Will result in
;	zero output. (2^0 = 1, but x is always less
;	than 1)
;
; 30 Sep 2000 by Nikolai Golovchenko
; 02 Oct 2000 debugged by Daniel Schouten [daniels at XS4ALL.NL]
;************************************************
exp2
;Form table index from 4 higher bits of x2 fraction part
        rlf x2lo, f
        rlf x2hi, 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 xhi
        clrf xlo
        movf templo, w
        subwf xlo, f
        movf temphi, w
        skpc
         incfsz temphi, w
          subwf xhi, 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 xlo, w
        addwf templo, f
        movf xhi, w
        skpnc
         incfsz xhi, 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 xhi:xlo
        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 xhi, f      ;rotate x right 2 times
        rrf xlo, f      ;to make easy multiplication.
        rrf temp, f     ;lower bits will go to temp
        rrf xhi, f
        rrf xlo, 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 xlo, f
        skpc
         decf xhi, f

exp2loopnext
        rrf xhi, f
        rrf xlo, f
        rrf temp, f
        decfsz index, f
         goto exp2loop
;shift the result 8 bits left
        movf xlo, w
        movwf xhi
        movf temp, w
        movwf xlo

;Now we will shift x 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

        tstf x2hi
        skpnz
         return         ;done

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

;if fractional part is zero than set carry, else
;clear carry
	movf xlo, w
	iorwf xhi, w
	setc
	skpz
	 clrc
;limit number of si
;perform shifts
exp2loop2
        rrf xhi, f
        rrf xlo, f
        clrc
        decfsz x2hi, f
         goto exp2loop2
        return          ;done

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
;************************************************



file: /Techref/microchip/math/power/2x-16b-ng.htm, 10KB, , updated: 2000/10/3 14:06, local time: 2024/10/4 01:43,
TOP NEW HELP FIND: 
3.238.82.77:LOG IN
©2024 PLEASE DON'T RIP! THIS SITE CLOSES OCT 28, 2024 SO LONG AND THANKS FOR ALL THE FISH!

 ©2024 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?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://www.piclist.com/techref/microchip/math/power/2x-16b-ng.htm"> PIC Microcontoller Math Method 2 ^ X 16 Bit 0.16 notation</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?

  PICList 2024 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!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  .