View previous topic :: View next topic |
Author |
Message |
neurus
Joined: 31 Mar 2004 Posts: 23 Location: Switzerland
|
Division 2 16Bits Integer with remainder? |
Posted: Mon Apr 18, 2005 7:01 am |
|
|
Hi
I want to divide two 16Bits Integer digits and shown it on the display with 2 digits after the comma ( remainder ). F. e.:
Result = int1 * 100 / int2
The division has to be as exactly as possible. Wich method can you recommd me?
I'm working with CCS and pic18f252
Thank you
Pablo |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Mon Apr 18, 2005 9:38 am |
|
|
Here is what I'd do.
Code: | printf(lcd_putc,"int1/int2 = %lu.%02lu", int1/int2, ((int1 % int2)*100)/int2); |
This example will print the answer on an lcd, thus the "lcd_putc" in there. What it does is first prints the result of the integer division, followed by a decimal point, . , then two digits of the fractional part. The "02" tells the printf function to print 2 digits, and leading zeroes.
The modulus (%) operator is used to get the remainder of the division which is multiplied by 100, and divided by int2 again to get the fractional portion.
For example, 3059/1127 = 2 using integer division, with a remainder of 805. 100 * 805 = 80500/1127 = 71. "2.71" will be printed.
If you want to be really accurate, you should take care of rounding the last digit based on the second remainder. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Apr 18, 2005 10:27 am |
|
|
Nice trick!! I forgot about that one.
Just a small remark: the intermediate answer will not always fit in a 16-bit variable (see the 80500 from the example). You can solve this by adding a cast to int32. Most other compilers would insert the cast to int32 automatically, but CCS can not always be trusted on this. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Mon Apr 18, 2005 10:32 am |
|
|
Doh!!! I didn't catch that (80500 being too big for an int16.) Thanks! |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Mon Apr 18, 2005 10:53 am |
|
|
If you want to save code space by avoiding the 32-bit integer division, then you can multiply by 10 i.s.o. 100 and apply the same trick multiple times.
In fact, by placing it in a loop you can then generate as many digits as you want.... This is how we learned to do divisions at primary school. |
|
|
neurus
Joined: 31 Mar 2004 Posts: 23 Location: Switzerland
|
|
Posted: Tue Apr 19, 2005 12:08 am |
|
|
hi
thank you very much for your answers. I will test your recommendations.
What about floating point? What do you mean? Is it better, if I calculate the division with integer or float digits?
Aloha Pablo |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Tue Apr 19, 2005 12:20 am |
|
|
Floats have their place, but it's usually best to avoid them. They take more time to calculate when compared to doing the same thing with integers. I believe that they also consume more memory (both RAM & program ROM) too.
I had an application where I tried to do a task using floats. My ROM usage (18F452) went ballistic when I tried to implement the routines. The ROM usage was ridiculous.....I remember something like 30% of the available ROM evaporated when I compiled my routine. That's when I switched to ints, and saved a lot of ROM, but at the expense of much more coding time. |
|
|
Guest
|
|
Posted: Tue Apr 19, 2005 2:07 am |
|
|
hi newguy
thanks for your answer. I tested the division with integer and I'm not satisfied with the result. I'm fortunate that my application is a slower application and I've enough memory to program. Here is my code:
Code: |
inte1 = (int32)int16TurbiValue;
inte2 = (int32)int16TurbiEndValue;
printf(lcd_putc,"int1/int2 = %lu.%02lu", 100*int1/int2, ((int1 % int2)*100)/int2);
|
Code: |
floatTurbiValue = (float)int16TurbiValue*(float)nMaxValue/(float)int16TurbiEndValue;
|
I've obteined a difference beetwen float and integer division from 0.02 on the display. Why is it so?
Thanks Pablo |
|
|
neurus
Joined: 31 Mar 2004 Posts: 23 Location: Switzerland
|
|
Posted: Tue Apr 19, 2005 2:37 am |
|
|
hi
I'm the guest!!
Quote: |
I've obteined a difference beetwen float and integer division from 0.02 on the display. Why is it so?
|
the difference is about 0.2 and not 0.02.
Sorry
Thanks Pablo |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Tue Apr 19, 2005 6:28 am |
|
|
This is a recurrent issue in this forum. Use of float has the advantage of
high arithmethic resolution at expenses of PIC memory resources.
Micromega Corporation has just released a 32-bit floating point
coprocessor, the uM-FPU that can be interfaced with microcontrollers
using I2C or SPI. It is a 8 PIN device and can do most of the arithmetic
operations either using float or long integers with the capabilities
of cross conversion between them.
I donīt tested yet, itīs very new and Iīm trying to get one sample (in
Argentina this is not a trivial task)
I would like to know some comments from the forumīs gurues.
Humberto |
|
|
Guest
|
|
Posted: Tue Apr 19, 2005 10:16 pm |
|
|
test |
|
|
|