=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Date: Fri, 25 Feb 2000 09:26:18
From: Nikolai Golovchenko
To: pic microcontroller discussion list
Subject: Re: fast % routine
--------------------------------------------------------------------------------
Nice done, Scott!
To add, if Tony needs a little better precision (especially for higher
values of input byte), one more term should be added, so that
d = (((h >> 3 + h) >> 3 + h) >> 1 + h) >> 2 = h * (1/4 + 1/8 + 1/64 +
1/512)
This adds only 6 cycles, and reduces errors from 51 to 11 cases per
all combinations of input (in both routines absolute errors are small,
+-1).
> MOVWF temp ;Hex value is in W.
> CLRC ;Clear the Carry bit so it doesn't affect RRF
RRF temp,F
CLRC
RRF temp,F
CLRC
RRF temp,F
ADDWF temp, F
> RRF temp,F
> CLRC
> RRF temp,F
> CLRC
> RRF temp,F ;temp = h>>3
> ADDWF temp,F ;temp = h + (h>>3)
> RRF temp,F ;temp = (h + (h>>3)) >> 1
> ADDWF temp,F ;temp = h + ((h + (h>>3)) >> 1)
> RRF temp,F
> CLRC
> RRF temp,W ;d = W = (h + (h + (h>>3)) >> 1) >> 2
> RETURN
Nikolai
On Friday, February 25, 2000 Scott Dattalo wrote:
> On Fri, 25 Feb 2000, Tony Nixon wrote:
>> Hi all,
>>
>> I need a fast 0 - 255 -> % routine
>>
>> Eg Byte value = 89
>> % value = 34
>>
>> 89 / 255 * 100
>>
>> I did this routine - any others??
>>
>> Value in W on entry
>> Result in PcntH on return
>>
>> ToPcnt movwf PCntH
>
> You mean like this:
> ;*******************************************************************
> ;scale_hex2dec
> ; The purpose of this routine is to scale a hexadecimal byte to a
> ;decimal byte. In other words, if 'h' is a hexadecimal byte then
> ;the scaled decimal equivalent 'd' is:
> ; d = h * 100/256.
> ;Note that this can be simplified:
> ; d = h * 25 / 64 = h * 0x19 / 0x40
> ;Multiplication and division can be expressed in terms of shift lefts
> ;and shift rights:
> ; d = [ (h<<4) + (h<<3) + h ] >> 6
> ;The program divides the shifting as follows so that carries are
> automatically
> ;taken care of:
> ; d = (h + (h + (h>>3)) >> 1) >> 2
> ;
> ;Inputs: W - should contain 'h', the hexadecimal value to be scaled
> ;Outputs: W - The scaled hexadecimal value is returned in W
> ;Memory: temp
> ;Calls: none
> scale_hex2dec
> MOVWF temp ;Hex value is in W.
> CLRC ;Clear the Carry bit so it doesn't affect RRF
> RRF temp,F
> CLRC
> RRF temp,F
> CLRC
> RRF temp,F ;temp = h>>3
> ADDWF temp,F ;temp = h + (h>>3)
> RRF temp,F ;temp = (h + (h>>3)) >> 1
> ADDWF temp,F ;temp = h + ((h + (h>>3)) >> 1)
> RRF temp,F
> CLRC
> RRF temp,W ;d = W = (h + (h + (h>>3)) >> 1) >> 2
> RETURN
> ?
> Scott