Author Topic: Decimal point variables in AVR C  (Read 9211 times)

0 Members and 1 Guest are viewing this topic.

Offline airman00Topic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 3,650
  • Helpful? 21
  • narobo.com
    • Narobo.com - Mechatronics and related
Decimal point variables in AVR C
« on: July 22, 2009, 02:31:45 PM »
How can I have decimal points stored in variables in C for AVRs?
If I do 10/4 , i'll end up with 3 because it rounds ( or it could be 2 if it rounds down). But really 10/4 = 2.5
I know that you can do the following: 10/4 --> 100/4 = 25 and there is an imaginary decimal point between 2 and 5 and all your code has to "remember" that.

How can I have the answer with a decimal point so I can basically have
decimal_point_int = 10/4;
Check out the Roboduino, Arduino-compatible board!


Link: http://curiousinventor.com/kits/roboduino

www.Narobo.com

Offline Stephanie

  • Jr. Member
  • **
  • Posts: 46
  • Helpful? 0
Re: Decimal point variables in AVR C
« Reply #1 on: July 22, 2009, 03:35:38 PM »
int stands for integer, so you can't have a "decimal point int".

You could use a floating point variable instead, like float.
Code: [Select]
float answer;
answer = 2.5;

Hope this helps.

Edit:
By the way, integer variables always round down.
« Last Edit: July 31, 2009, 12:06:16 AM by Stephanie »
--- Stephanie

Offline pomprocker

  • Supreme Robot
  • *****
  • Posts: 1,431
  • Helpful? 16
  • Sorry miss, I was giving myself an oil-job.
    • Nerdcore - Programming, Electronics, Mechanics
Re: Decimal point variables in AVR C
« Reply #2 on: July 22, 2009, 03:59:25 PM »
I don't think you can do float if you're using an 8-bit avr, but maybe you could store the base number and the decimal separately, and somehow come up with an algorithm that combines them when its time to do the math?

Offline Stephanie

  • Jr. Member
  • **
  • Posts: 46
  • Helpful? 0
Re: Decimal point variables in AVR C
« Reply #3 on: July 22, 2009, 04:12:46 PM »
My bad, I'm new to AVR programming. You mean like this?

base+pow(10,strlen(decimal)*(-1))*decimal

Example:
Code: [Select]
int base = 1, decimal = 25;
int result;
result = 4 * (base+pow(10,strlen(decimal)*(-1))*decimal); //result = 5
« Last Edit: July 22, 2009, 08:44:38 PM by Stephanie »
--- Stephanie

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,165
  • Helpful? 111
    • Webbot stuff
Re: Decimal point variables in AVR C
« Reply #4 on: July 22, 2009, 07:10:11 PM »
I don't think you can do float if you're using an 8-bit avr, but maybe you could store the base number and the decimal separately, and somehow come up with an algorithm that combines them when its time to do the math?

Nope. Stephanie is correct.

You can use float, double etc.

@Pomprocker Just because the AVRs are 8 bit doesn't mean that it can only deal with 8 bit integers. It just means that its data bus is 8 bit wide. So accessing a 16-bit integer will require 2 read cycles and will require 2 registers to hold the value. A float or double needs more space, more cpu cycles, but it CAN be handled.

--- EDIT --

@Airman - if you use floating point maths then you will probably need to make sure that you link in the relevant maths libraries. Otherwise you will get errors from the linker


-- Edit 2 --
Check out my post here for an alternative http://www.societyofrobots.com/robotforum/index.php?topic=7426.0
« Last Edit: July 22, 2009, 07:14:01 PM by Webbot »
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline Stephanie

  • Jr. Member
  • **
  • Posts: 46
  • Helpful? 0
Re: Decimal point variables in AVR C
« Reply #5 on: July 22, 2009, 08:59:25 PM »
Just because the AVRs are 8 bit doesn't mean that it can only deal with 8 bit integers. It just means that its data bus is 8 bit wide. So accessing a 16-bit integer will require 2 read cycles and will require 2 registers to hold the value. A float or double needs more space, more cpu cycles, but it CAN be handled.

Thanks for clarifying that. I was puzzled, because if an 8-bit AVR couldn't deal with variables higher than 8-bit, it wouldn't be able to handle even the standard C int (which is 16-bit).
« Last Edit: July 22, 2009, 09:28:53 PM by Stephanie »
--- Stephanie

Offline chelmi

  • Supreme Robot
  • *****
  • Posts: 496
  • Helpful? 15
    • Current projects
Re: Decimal point variables in AVR C
« Reply #6 on: July 23, 2009, 08:57:14 AM »
Floating points operations are really expensive on AVR microcontrollers. There is no floating point unit to perform them in hardware and they have to be done in software. Not to mention the program size that will increase significantly. Look at fixed point operation, they might be working for your application.

Chelmi.

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,165
  • Helpful? 111
    • Webbot stuff
Re: Decimal point variables in AVR C
« Reply #7 on: July 23, 2009, 01:19:58 PM »
Yeah the floating point libraries are about a 2k - 3k overhead. And yes they are slow - as it has to be done it software.

Try to avoid them if you can - but sometimes they are necessary - ie if you are trying to convert a logarithmic sensor reading to a linear value. OK you may be able to simulate it with an integer look up table - but eventually the size of the lookup table (if its gonna be accurate) plus other lookup tables you may use (ie for sin/cos/tan and other sensors) may be more than the space taken by the floating point table, That is why the AxonLib from Admin now uses floating point maths when converting raw sensor readings into real-world values (ie cm, mm, amps etc).

My own lib tries to the fraction method (linked to earlier) if the conversion ratio is linear. Its only when you get into non-linear mappings that it 'gives up' and links in the floating point libs.


So on something like the Axon where there is loads of program space then its easier to just link the floating point libs and be done with it. Smaller devices may need you to find an alternative using integers.
Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline Admin

  • Administrator
  • Supreme Robot
  • *****
  • Posts: 11,703
  • Helpful? 173
    • Society of Robots
Re: Decimal point variables in AVR C
« Reply #8 on: July 24, 2009, 12:11:23 PM »
Yea, I avoid floating point if at all possible, except when I'm too lazy to do an alternative. Its better to multiply everything by 10^x. For example:

slow:
5.5/5.5 = 1

faster:
55/55 = 1

Also maybe of interest to you is modulus:

5/2 = 2
5%2 = 0.5

Or to avoid floats for a 5/2 calculation:
5/2 = 2
5%2*10 = 5

(the solution is 2.5)

Offline airman00Topic starter

  • Contest Winner
  • Supreme Robot
  • ****
  • Posts: 3,650
  • Helpful? 21
  • narobo.com
    • Narobo.com - Mechatronics and related
Re: Decimal point variables in AVR C
« Reply #9 on: July 25, 2009, 10:18:37 PM »
Thanks for all the replies. Big thanks to Stephanie.
This code works
Code: [Select]
float test;
test = 2.5;
rprintfInit(uart2SendByte);
rprintfFloat(3,test);

syntax: rprintfFloat(digits to show,variable or number)
Code: [Select]
rprintfFloat(4,5.667);  // displays the 4 digits of the number 5.667
Check out the Roboduino, Arduino-compatible board!


Link: http://curiousinventor.com/kits/roboduino

www.Narobo.com

Offline jka

  • Full Member
  • ***
  • Posts: 78
  • Helpful? 4
Re: Decimal point variables in AVR C
« Reply #10 on: July 26, 2009, 12:54:29 AM »
I haven't worked with AVR's but this works with PICs

In stdlib.h there is a struct called div_t that contains the quotient and remainder from a division using the div function. It uses integer division, so you shouldn't get the overhead by using floats.

see http://www.chemie.fu-berlin.de/chemnet/use/info/libc/libc_14.html#SEC266

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,165
  • Helpful? 111
    • Webbot stuff
Re: Decimal point variables in AVR C
« Reply #11 on: July 27, 2009, 12:26:39 PM »
That still only works with integer maths.

Its main purpose is if you want to divide say 13 by 5 and get the integer answer 2 and the remainder 3 - all in one go. If you need both the answer and the remainder then this is more effeicient than performing a ' / ' to get the answer and then a modulus ' % ' to get the remainder.

Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

Offline sonictj

  • Supreme Robot
  • *****
  • Posts: 416
  • Helpful? 11
    • Tim's Workshop
Re: Decimal point variables in AVR C
« Reply #12 on: July 27, 2009, 01:35:41 PM »
Can't you also write 5/3 as 5/3.0 to receive a decimal number?  I'm nearly positive I've done this with AVR's.  You just have to declare a float or double right?

Offline Webbot

  • Expert Roboticist
  • Supreme Robot
  • *****
  • Posts: 2,165
  • Helpful? 111
    • Webbot stuff
Re: Decimal point variables in AVR C
« Reply #13 on: July 27, 2009, 02:00:23 PM »
Can't you also write 5/3 as 5/3.0 to receive a decimal number?  I'm nearly positive I've done this with AVR's.  You just have to declare a float or double right?

The compiler looks at the datatypes on the left and right hand side of the equals sign. If any of them are 'floating point' then it will perform floating point maths.

On the left side of the '=' then a 'float' or 'double' variable type is a 'floating point'.
On the right hand side of the '=' then it will look at any variables you may have used to see if any are 'float' or 'double', and any functions that return 'float' or 'double', and then it will look at the literals (ie the number you have typed). If the literal contains a '.' then it will pretend it is a double. So '3.0' is treated as a double. Most compilers also allow you to use 'f' for float or 'd' for double at the end of a number. So '3f' is a float with a value of 3.

Note that this means that:-
int result = 5.0 / 2.0;
is a bit of a waste of space in that the numbers to the right of the '=' are floating point and will come up with the answer '2.5' but this is then cast to an integer (ie '2') to store in the 'result' variable. So this may well link in the floating point libraries un-necessarily.


Webbot Home: http://webbot.org.uk/
WebbotLib online docs: http://webbot.org.uk/WebbotLibDocs
If your in the neighbourhood: http://www.hovinghamspa.co.uk

 


Get Your Ad Here