piclist 2000\09\28\075821a >
www.piclist.com/techref/microchip/math/index.htm?key=math
BY : Nikolai Golovchenko email (remove spam text)

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
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
movf x2hi, w
skpnc
incf x2hi, 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
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-requestmitvma.mit.edu

<1115014241.20000928144929@yahoo.com> 7bit