3

I'm very new to Arduino and I am making a code for a pedometer. I have a lot of variables and I have used "int" multiple times, but I just came across a code with "float". Now because my coding background is next to none, I don't really understand the concept of a float and when it's appropriate to use one. Could someone please give me an explanation. Thanks!

  • use them for intermediate division in places map() won't work – dandavis Feb 19 '17 at 7:32
3

"int" means integer. It's either one whole number (forgive me, mathematicians, for the sloppy definition!) or the next or previous.

A "float" is a floating-point number - that is, a number and part of a number.

3 is an int

3.14 is a float

If you need to store/represent a value that can be between integers, you could use a float.

Floats use more RAM than integers, and there is a limit to the precision they can represent. Don't use a float unless you have a need.

3

An integer is a whole or natural number. Computers use integers for counting and comparisons. Computers can count precisely using integers and comparisons of two integers can be absolutely true or false.

To make a float or floating-point number, a computer uses two integer numbers. It uses one integer as the mantissa and the other as the exponent. Computers use floats for calculations involving very large, very small or fractional values. In other words the set of real numbers. Computers can not count very well using floats. Computer can not even compare two floats very well. That is to say, you may get different results from different computers when testing if two different floats are the same or not. This is due to rounding error.

Consider that the set of real numbers between 0 and 1 to be infinite. However, intuitively, we know computers can not keep track of an infinite number of unique values between 0 and 1. After all, computers use a float to do this and a float has a finite number of bits in it's mantissa and exponent. The difference, if any, between the actual real number from, say, a calculation and the next possible float value is commonly referred to as the roundoff error. In a program, a difference, for example, in the order of operation is enough to cause different roundoff errors to occur resulting in two slightly different float value results.

Rounding errors are what we end up with for allowing float values to grow very large or very small or to contain factional amounts. Fortunately, floats are exactly what we need when computers are asked to calculate very large, very small or fractional numbers.

In embedded programming we rarely use floats. They take up more of our limited RAM space than integers. And it is rare that we need to calculate very large or very small numbers. Usually, in embedded programming, we are counting events or measuring sensors. Usually integers are preferred or are sufficient for our purposes.

Addressing your specific application (pedometer):

It is anticipated you would prefer to track distances in miles. And it is practical to assume a good pedometer displays factional miles. You can use floats to calculate this value. A rigorous programmer would cast their integers as floats when mixing them in equations to make it clear to the compiler what is desired.

  • > Computer can not even compare two floats very well. This is very wrong. Computers can easily compare two floats. You just have to know exactly why (on a particular CPU) float x=1.1; bool ok=x==1.1; results in not ok. Mandatory reference is What Every Computer Scientist Should Know About Floating-Point Arithmetic. – Ruslan Feb 18 '17 at 9:07
  • I appreciate the rigorousness of your comment. I will reword my answer. – st2000 Feb 18 '17 at 13:40
  • 1
    @st2000: You wrote: “[floats] always have a certain amount of imprecision”. This is incorrect, floats are exact numbers. Only the operations done on them may incur rounding error. @Ruslan: You wrote: “float x=1.1; bool ok=x==1.1; results in not ok”. On most Arduinos (the AVR-based ones) it results in ok. – Edgar Bonet Feb 18 '17 at 22:42
  • @EdgarBonet OK, I was right to note "particular CPU". Your comment is quite interesting though. AFAIR, AVRs don't have FPU, so float should be "emulated" in software. Based on your comment though, it seems that this emulation makes float and double identical. What is your compiler? – Ruslan Feb 19 '17 at 5:05
  • @Ruslan: It's gcc, which is the standard for Arduino. You are absolutely right. AVR floats are implemented in soft, and double is implemented the same as float. – Edgar Bonet Feb 19 '17 at 8:19
0

There are much more details on both data types, but to keep it easy, just a rough explanation:

integer data types only allow a range from -2,147,483,648 to 2,147,483,647 with 4 Bytes of memory per variable.
If your results exceed that numbers, an over- or underflow will occur. If you don't take care, bad things can happen.
And you can only use whole numbers, there is no decimal point.

float instead allows you to do your calculations directly typing decimal values (like 1.25, 3.14, ...), just like you do on paper.
Plus: You usually don't have to care for range checks, because that data type covers a huge value range (-3.4028235E+38 to 3.4028235E+38 with also only 4 Bytes of memory per variable!

So why not use float by default?
One big drawback is that handling this number format requires a special piece of hardware ("Floating Point Unit", FPU) to be efficient.
If your microcontroller doesn't have an FPU (and the small Arduinos don't have one), every calculation using float operands requires to call certain functions which use some rules to convert your float operands into integer data types, do the calculation on integer basis and convert the result back to float.
This consumes some memory and a lot of CPU cycles, which can slow down calculation speed to about 1/10 compared to using an FPU.

There are some other issues which make working with float a little bit tricky, so if your calculation can be done using integer, use this instead.

"And what if i need decimal numbers?"
You can't type 3.14 in integer, but you can multiply it to a value big enough to consider enough decimal places for your application. You just have to define the factor and imagine the decimal point. For instance, multiply your values by 1000, then 3.14 * 1.256 = 3.94384 becomes 3140 * 1256 = 3943840 internally.

0

I'm very new to Arduino and I am making a code for a pedometer.

others have answered the difference between float and int.

but your project offers an interesting challenge in that it covers a wide range: the pedometer likely counts in miles and have to keep track of total steps, which the increments are done in single steps - much shorter than miles.

what you could do instead of using floats is to use multi-byte types. for example, a 32-bit/4-byte type can support 2 million miles; you can add additional msb to it to create a proprietary data type. a 5-byte type for example would support 5 million miles, and a 128 billion miles for a 6-byte type.

you will need to create your own math routines -> not difficult at all.

the point is that float is a simple solution to simple problems only.

  • There are tons of scientific computations done with floats. And no, not only simple problems. – Edgar Bonet Feb 20 '17 at 21:36
0

When is it necessary to use “float” instead of “int”?

IMHO in Arduino world it is never necessary to use float ; well unless you want to do something very fancy like building a space ship route calculation with Arduino. In which case you will have someone on your team who understands the problem in full detail who can decide it is better to use float for some calculations.

How do I deal with behind the comma numbers?

As integers does not allow you to work behind the coma and you won't use float you may wonder how to work with pi (3.1415..radians). In most cases you will only work with a specific number of digits behind the comma. Lets say you want 3 digits behind the comma. In this case you simply work with milli radians instead of radians ( 3145 milli radians=3.145 radians; For the Americans it might be time to look at the metric system for a better understanding)
Because of this change in "base value", no more floats are needed to calculate. There are 3 drawbacks:

  • when out-putting information formatting may be needed/desired to convert to a user "base value".
  • when in-putting information formatting may be needed/desired to
    convert to a user "base value".
  • When using methods that use float conversions are needed In and output are normally very small in arduino. The Serial.print() is probably the biggest thing.
    If you need to use a method like cos() you do as follows:
    long result=DECIMALDIGITS*cos((float)corner/DECIMALDIGITS);
    Where DECIMALDIGITS= (float)10^numdigits;

As type I advice to use long on a 8 bitter as int (-32,768 to 32,767) is very likely to get out of range.

More background behind the dirty details of float
It is pretty obvious that float supports behind the comma values, but what are the disadvantage of float?

  • float is CPU/RAM intensive
  • float introduces a rounding problem.
  • multiple types int/float can cause casting issues

Lets go through the disadvantages one by one:
float is CPU/RAM intensive
IMHO In many Arduino projects there is plenty of CPU/RAM left so I don't think this is a real issue.
To prove this point look at how many Arduino projects contain a delay(x00) in the loop; so if things go to slow simply decrease this number to release some CPU cycles ;-).

float introduces a rounding problem.
*When using floats A * B / A does not guarantee to be equal to B!!!* It will be close but ...
This is my main argument to avoid floats. Sooner or later this will hit you and you'll have a hard time finding out why. (I speak from experience here)
Basically 0.1 can not be represented 100% exactly in float. So in float 0.1+0.2 is not equal to 0.3!!!

multiple types int/float can cause casting issues In C/C++ it is pretty hard to predict the casting that will happen in a formula like:

float z;
byte r;
uint32 t;
...
int a=z*r/t*1.5;

I consider myself very experienced in C/C++ and I always convert code like this into something like

float z;
byte r;
uint32 t;
...
byte rfloat=r;
uint32 tfloat=t;
int a=(int)(z*rfloat/tfloat*1.5);

I prefer not to explain this to a newbie Arduino user :-s.
More in depth details can be found at floating-point-gui.de

  • 1
    While in principle I agree with you, it should be noted that the alternative, namely fixed point arithmetic, is hard, especially for the novice: you have to figure out the proper scaling to apply to your numbers at every step of every calculation. With floats, in contrast, the optimum scaling is automatically computed at run time. – Edgar Bonet Feb 20 '17 at 18:59
  • In Arduino world I would disagree. The answer is: Take long. int goest to +-32.700 so is probably to small for cents and for sure to small for millis. Long still has a huge cpu and memory gain compared to float. – jantje Feb 20 '17 at 21:16
  • And do not forget. In Arduino world the biggest input is 1023 from the analog read. I challenge you to give a example where long is not long enough for a "normal" arduino project. So no space travelling – jantje Feb 20 '17 at 21:25
  • 1
    No, long is not the universal answer. Sometimes the cost of writing a fixed-point code is just not worth the trouble if you have enough time to do it with floats. You could certainly compute a cos() using only integers (I did it), but you cannot expect a novice to do that. – Edgar Bonet Feb 20 '17 at 21:35
  • I do not advice to write your own cos only using integere. I'll mod the answer. – jantje Feb 20 '17 at 22:29
0

int stands for Integer and float stands for floating point number. For more reference check this out https://www.arduino.cc/reference/en/language/variables/data-types/float/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.