Searching \ for 'fast % routine' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: massmind.org/techref/index.htm?key=fast+routine
Search entire site for: 'fast routine'.

Truncated match.
PICList Thread
'fast % routine'
2000\02\24@205608 by Tony Nixon

flavicon
picon face
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
         movwf tempL
         clrf PCntL
         bcf status,carry
         rrf PCntH
         rrf PCntL
         rrf PCntH
         rrf PCntL
         rrf PCntH,w
         movwf tempH
         rrf PCntL,w
         call addup
         clrf tempH
         bcf status,carry
         rlf tempL
         rlf tempH
         rlf tempL
         rlf tempH
         movf tempL,w
         call addup
         return

addup     addwf PCntL
         btfsc status,carry
         incf PCntH
         movf tempH,w
         addwf PCntH
         return


--
Best regards

Tony

http://www.picnpoke.com
spam_OUTsalesTakeThisOuTspampicnpoke.com

2000\02\24@214213 by Scott Dattalo

face
flavicon
face
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

<big snip>

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

2000\02\24@225823 by Tony Nixon

flavicon
picon face
Scott Dattalo wrote:

> You mean like this:
[snip]


Gee Scott, what took you so long :-))

--
Best regards

Tony

http://www.picnpoke.com
.....salesKILLspamspam@spam@picnpoke.com

2000\02\24@233843 by Scott Dattalo

face
flavicon
face
On Fri, 25 Feb 2000, Tony Nixon wrote:

> Scott Dattalo wrote:
>
> > You mean like this:
> [snip]
>
>
> Gee Scott, what took you so long :-))

Well, the first one was a fast mod routine and then it dawned on me you
meant percentage :).

If you look closely, it doesn't do exactly what you asked. The one I
posted divides (implicitly) by 256 while you were asking for 255. The
error is quite small, but if necessary can be removed.

You're asking for

p = x * 100/255

and I gave you a solution for

p' = x * 100/256

but you can do a little arithmetic:

p = x * 100/256 * (256/255)
 = p' * (256/255)
 = p' * (1 + 1/255)
 = p' + p'/255

and,

1/255 = 1/(-1+256) = 1/256 * ( 1 + 1/256 + 1/256/256 + ...)

p = p' + p'/256 + p'/256/256 + ...

Now since p' is going to be less than 100, then the first correction is
going to be less than 1/2 and there will be no rounding. Hence the answer
IS the same. However, if you wanted a fractional result, well here you go.
Looks like you get a repeating fraction much like you get when you divide
by 9 (10 - 1 instead of 256 - 1).

Scott

2000\02\24@235542 by Tony Nixon

flavicon
picon face
Scott Dattalo wrote:

> Well, the first one was a fast mod routine and then it dawned on me you
> meant percentage :).

I actually tested the routine with 256 and it doesn't make a great deal
of difference (if any). I was going to dump it into Excel, but no time
yet.

Thanks anyway, I've already implemented it.

--
Best regards

Tony

http://www.picnpoke.com
salesspamKILLspampicnpoke.com

2000\02\25@003330 by John Orhan

flavicon
face
Hi Guys,
Could you explain that one more time for the dummy?

                                               John

               {Original Message removed}

2000\02\25@023354 by Nikolai Golovchenko

flavicon
face
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
{Quote hidden}

Nikolai

On Friday, February 25, 2000 Scott Dattalo wrote:
{Quote hidden}

2000\02\25@053806 by Michael Rigby-Jones

flavicon
face
This was done last year some time IIRC.  I offered a simmlar (although
nowhere near as good as Scotts solution) that also divided by 256 instead of
255.  There was a long thread regarding "fixing" this error, I'll have to
trawl through the archives and see what the conclusion was...

Cheers

Mike

> {Original Message removed}

2000\02\25@093716 by Jason Harper

picon face
> I need a fast 0 - 255 -> % routine
>
> Eg Byte value = 89
> % value = 34
>
> 89 / 255 * 100

The fastest routine, of course, would be a 256 byte lookup table...

Assuming that code space is also a concern, try this: it's a bit shorter
than the other solutions I've seen posted.  Note that it actually
calculates input * 102 / 256, but due to roundoff errors it produces 100
for an input of 255, so it should do the job for you.

percentify
; input in W, output in temp
       movwf temp
       bcf status,c
       rrf temp,f              ;temp = input * 128 / 256
       addwf temp,f            ;carry/temp = input * 384 / 256
       rrf temp,f              ;temp = input * 192 / 256
       bcf status,c
       rrf temp,f              ;temp = input * 96 / 256
       swapf temp,w
       andlw 0x0F              ;w = input * 6 / 256
       addwf temp,f            ;temp = input * 102 / 256
;or:    addwf temp,w     for result in w
       return


       Jason Harper

2000\02\27@181313 by Dmitry Kiryashov

flavicon
face
Hi Scott.

Nice code ;-)

{Quote hidden}

Possible realization of 1 + 1/256 + ... correction.

;1/256 * (1 + 1/256) =~ 0.999985 / 255 ;

scale255to100:                  ;25 = 16+8+1
       clrf    temp            ;int
       clrf    temp1           ;frac

       addwf   temp,F          ;1
       rrf     temp,F          ;/2
       rrf     temp1,F

       rrf     temp,F          ;/4
       rrf     temp1,F
       rrf     temp,F          ;/8
       rrf     temp1,F

       addwf   temp,F          ;8
       rrf     temp,F          ;/16
       rrf     temp1,F

       addwf   temp,F          ;16
       rrf     temp,F          ;/32
       rrf     temp1,F

       rrf     temp,W          ;/64
       rrf     temp1,F
;
;       movwf   temp2           ;1/256/256     if longer tail
;       movwf   temp3           ;1/256/256/256 is required
;       etc...
;
       addwf   temp1,F         ;1 + 1/256 correction
       btfss   temp1,7         ;either round if >= 0.5
       skpnc                   ;or take carry
       addlw   1               ;temp1 holds frac part
;
;       movwf   temp            ;answer is either W or temp
       return

If >=0.5 correction isn't required <btfss temp1,7> line
should be commented.

WBR Dmitry.

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