Searching \ for 'Doing ratio or percentage' in subject line. ()
Help us get a faster server
FAQ page: www.piclist.com/techref/index.htm?key=doing+ratio+percentage
Search entire site for: 'Doing ratio or percentage'.

Truncated match.
PICList Thread
'Doing ratio or percentage'
1999\09\28@044202 by

Hi
I want to get a result from two values where as the result is a ratio
(or percentage?) from one value to the other:

Register A is the ratio amount (anything from 0 to 0x0FF, representing 0
to 100% if you want). I want to apply this to the value in Register B
and get a result in say Register C.

Before I go into complex division, anybody got a simple routine to do
this in Assembler?

Thanks
Quentin

part 0 1111 bytes content-type:application/octet-stream;C = (A*B)/256

The 256 number is handy as no division is actually needed, you just take the
most significant byte of the 16 bit result.

Hope this is of some use.

Mike Rigby-Jones

<<MULT8X8F.ASM>>

> {Original Message removed}
On Tue, 28 Sep 1999 11:43:13 +0100 Michael Rigby-Jones
<mrjonesNORTELNETWORKS.COM> writes:
>These are 8 bit values right?  This is pretty simple, you need to
>steal a
>multiply routine from somewhere that does 8bit * 8bit with a 16 bit
>result.
>The Microchip routine is attached (no flames please...it's tiny) The
>idea
>is:
>
>C = (A*B)/256
>
>The 256 number is handy as no division is actually needed, you just
>take the
>most significant byte of the 16 bit result.
>
>Hope this is of some use.
>
>
>Mike Rigby-Jones
>

I'm not sure if this is what the original poster wanted, but IF it is,
it's similar to some code I wrote to have a grand master control in a
lighting control system control the outputs of the A/D values from the
original channel pots.
There we have individual channel pots giving A/D values from 0 to 255
(0x00 to 0xff).  The master pot gives the same result.  We want the
master pot to scale the channel pots.  Turns out simple enough...

Out = Chan * Master/255

Note that it's divided by 255, not 256.  Otherwise, if both channel and
master were 255, we'd get 254 as an output, when we want 255.
Dividing by 255 is certainly not as easy as dividing by 256 (throwing
away the bottom 8 bits).  Perhaps with rounding that would work (divide
by 256 and if bit 7 of the remainder is 1, increment the result).  What I
did was to check bit 7 of the master pot value.  If it's 1, I added 1 to
the result of the divide by 256.  Works great!

Harold

___________________________________________________________________
Get the Internet just the way you want it.
Free software, free e-mail, and free Internet access for a month!
Try Juno Web: dl.http://www.juno.com/dynoget/tagj.

On Tue, 28 Sep 1999, Harold Hallikainen wrote:

{Quote hidden}

I'm not sure what Quentin wants. Quentin?

If you want a quick and easy routine to scale a number to a percentage:

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

For Harold's case:

C = A*B/255

There is another trick that you can attempt. Recall the power series for
division:

N        N    /     / e \   / e \2  / e \3      \
-------  = --- * | 1 - |---| + |---| - |---| + ... |
v + e      v    \     \ v /   \ v /   \ v /       /

In Harold's equation, N=A*B, v+e = 255. If you let v=256 and e=-1 then the
series simplifies to:

A*B      A*B    /    / 1 \   / 1 \2  / 1 \3      \
--------  = --- * | 1 + |---| + |---| + |---| + ... |
256 - 1    256    \    \256/   \256/   \256/       /

Or just keeping the first two terms:

A*B       A*B    /     1  \
--------  ~= --- * | 1 + --- |
255       256    \    256 /

If A & B are 8-bit quantites, then the second term in the series would
produce 0 (you'd be dividing the product A*B by 256 twice). However, as
Harold notes, you may use the second term to round the result.
Specifically, if you treated the multiplication (conceptually) as floating
point then you'll end up with a fractional component that's greater than
0.5 if A*B is greater than 2^15. Or stated differently, if the most
significant bit is set in the product, then increment the result.

Scott

Scott Dattalo wrote:
>

> I'm not sure what Quentin wants. Quentin?
>
Money, lot's of it, hehe.

I haven't had time to run Mike's 8x8 routine to see if it will work. Let
my explain with an example:
RegisterA has a value of 128 (50%). RegisterB has a value of 40. I want
to apply registerA to B to get an answer of 20. IOW the answer is 50% of
registerB, and 50% is represented in registerA by 128.
So I want to get the percentage of registerB and the percentage value is
in registerA (0 to 255).
It is actually wrong to speak of percentage, that is why I call it ratio
(Reduce B by the ratio in A).

Clear now? Not a mathematician here :)

Quentin

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