=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
    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