Searching \ for '[PIC]: Multiplies and divides' in subject line. ()
Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/math/index.htm?key=divide
Search entire site for: 'Multiplies and divides'.

Exact match. Not showing close matches.
'[PIC]: Multiplies and divides'
2002\02\01@175219 by

Hello,

I need to multiply a byte by another byte and then divide this result by
255, like x = y * z / 255.

At this moment, I'm using CCS-PICC built-in maths, but it's very
inneficient. The execution time for this calculation is about 1200
instructions(!).

Someone have an idea of a very fast math function in assembly to make
this?

Best regards,

Brusque

-----------------------------------
Edson Brusque
Research and Development
C.I.Tronics Lighting Designers Ltda
Blumenau  -  SC  -  Brazil
http://www.citronics.com.br
Say NO to HTML mail
-----------------------------------

--

On Fri, 1 Feb 2002 20:50:46 -0200, Edson Brusque wrote:

>Hello,
>
>    I need to multiply a byte by another byte and then divide this result by
>255, like x = y * z / 255.
>
>    At this moment, I'm using CCS-PICC built-in maths, but it's very
>inneficient. The execution time for this calculation is about 1200
>instructions(!).
>
>    Someone have an idea of a very fast math function in assembly to make
>this?
>

take the upper byte of a 16-bit multiplication result. (Hard to get
much faster but this error may or may not meet your requirements.)

regards, Bob

--

On Fri, 1 Feb 2002, Edson Brusque wrote:

> Hello,
>
>     I need to multiply a byte by another byte and then divide this result by
> 255, like x = y * z / 255.
>
>     At this moment, I'm using CCS-PICC built-in maths, but it's very
> inneficient. The execution time for this calculation is about 1200
> instructions(!).
>
>     Someone have an idea of a very fast math function in assembly to make
> this?

This can be done in less than 40 cycles. Is that fast enough?

Hint: look at the http://www.piclist.com/

And remember that 1/255 = 1/256 + 1/256^2 + 1/256^3 ...

When done, I promise this will not take anywhere near a ridiculus 1200
cycles on SDCC. OTOH, I don't think it take just 40 either...

Scott

--

I did a divide by 255 once for 24 bits that went something like this:

/* good for up to 255*0xFFFF, that is 0x1000000 (16megs) - 0x100ff */
result = ((dividend+1 + ((dividend+1)/256) ) / 256);
*remainder = (dividend - (result*256)) + result;
*remainder = result + dividend - (result*256))

This is pseudo code that should actually work but I have optimized it for the
CCS from here.  IIRC, the main reason I did not use the above verbatim is to be
able to support 24 bits.  Keep an eye on the .LST file.

Of course the div and mult 256 is easy with shifts.  It was good (tested on a pc
platform with Borland C) to 16 Megs and saved a ton of code.  Since it works by
aproximation, sometimes the remainder needs adjustment.  That is the last two
statements.

David Koski
davidKosmosIsland.com

On Fri, 1 Feb 2002 20:50:46 -0200
Edson Brusque <ebrusqueTERRA.COM.BR> wrote:

{Quote hidden}

--

Edson Brusque <PICLISTmitvma.mit.edu> wrote:

> I need to multiply a byte by another byte and then divide this result
> by 255, like x = y * z / 255.
>
> At this moment, I'm using CCS-PICC built-in maths, but it's very
> inneficient. The execution time for this calculation is about 1200
> instructions(!).

Edson:

If you divide by 256 instead of 255 (which takes ZERO code and
ZERO
time), half of your results will be exactly correct and the other
half will only be off by 1.  Is that close enough for your
application?

-Andy

=== Andrew Warren -- aiwcypress.com
=== Principal Design Engineer
=== Cypress Semiconductor Corporation
===
=== Opinions expressed above do not
=== necessarily represent those of
=== Cypress Semiconductor Corporation

--

It is a shame you can not divide by  256 (if this creates an error in
computation that is withstandable then you can save a lot of time and space)
as all you would need to do is look at the high byte of the answer and no
division would be necessary,
to multiply, you could shift algorithms with early out checks, but this
would lead to larger program space with lower process times, speed and size
are unfortunately inversely proportional.
to multiply x by 36 you could copy x and shift the bits left by 5 = multiply
by 32 then shift the original x left by 2 = multiply by 4 then add the two
numbers giving x*32 + x*4   this could be done in only a few clock cycles.

{Original Message removed}
See http://www.piclist.org/techref/microchip/math/scale/index.htm

Good stuff there!

Harold

On Fri, 1 Feb 2002 20:50:46 -0200 Edson Brusque <ebrusqueTERRA.COM.BR>
writes:
{Quote hidden}

FCC Rules Online at http://hallikainen.com/FccRules
Lighting control for theatre and television at http://www.dovesystems.com

________________________________________________________________
GET INTERNET ACCESS FROM JUNO!
Juno offers FREE or PREMIUM Internet access for less!
Join Juno today!  For your FREE software, visit:
dl.http://www.juno.com/get/web/.

--

Hello Harold,

> See www.piclist.org/techref/microchip/math/scale/index.htm
> Good stuff there!

as you also work with lighting, you got what I need. :)

But it seens to me that those routines aren't exactly what I need.

I have two values let's say that one is the CHANNEL and other is the
MASTER as in the lighting consoles. Both values can be anywhere from zero to
255 and the result is 8 bits also, from 0-255.

The expression "RESULT = (CHANNEL * MASTER) / 255" is perfect. The
problem is that the execution time is very long.

Some examples :
X    Y    X*Y   /255   /256
0  255      0      0      0
48   47   2256      8      8
200  199  39800    156    155
210  210  44100    172    172
220  221  48620    190    189
230  230  52900    207    206
255  255  65025    255    254

If someone tell me a very fast way to make this I'll be eternally
grateful.

Thanks,

Brusque

-----------------------------------
Edson Brusque
Research and Development
C.I.Tronics Lighting Designers Ltda
Blumenau  -  SC  -  Brazil
http://www.citronics.com.br
Say NO to HTML mail
-----------------------------------

--

On Fri, 1 Feb 2002, Edson Brusque wrote:

{Quote hidden}

note 65025 = 0xfe01

Call that res_hi:res_lo

btfsc  res_hi_,7
incf  res_hi,F

and you'll be very close. There may be a few instances where this fails...

This is the hint I mentioned in the other post:

1/255 = 1/256 + 1/256^2 + 1/256^3 + ...

If you want to have more accuracy than what the two instructions provide
you could do this:

movf   res_lo,w
andlw  0x80

skpc
skpz
incf res_hi,f

That should be pretty accurate.

Scott

--

Hello Scott,

> note 65025 = 0xfe01
> Call that res_hi:res_lo

yes.

>   btfsc  res_hi_,7
>    incf  res_hi,F
> and you'll be very close. There may be a few instances where this fails...

Using this method, there'll be a gap between 127 and 129. A res_hi=128
(0b10000000) will incremented 129.

> This is the hint I mentioned in the other post:
> 1/255 = 1/256 + 1/256^2 + 1/256^3 + ...

Ohh, now I undestand it. I'm not exactly a binary math expert. :)

> If you want to have more accuracy than what the two instructions provide
> you could do this:
>    movf   res_lo,w
>    andlw  0x80
>    skpc
>    skpz
>    incf res_hi,f
> That should be pretty accurate.

Yep, this seens to be ok. Althought I don't understand the working of
this method very well:

movf   res_lo,w
addwf  res_hi,w   ; add res_lo and res_hi, put the sum on w
andlw  0x80       ; and the sum with 0x80, why?
skpc
skpz
incf res_hi,f     ; if carry or notzero increment res_hi (?)

I would love some explanations. I'm feeling dumb...

Thanks,

Brusque

-----------------------------------
Edson Brusque
Research and Development
C.I.Tronics Lighting Designers Ltda
Blumenau  -  SC  -  Brazil
http://www.citronics.com.br
Say NO to HTML mail
-----------------------------------

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics

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