Float addition oddity

void loop()
{
float aaa;
int a;

  aaa = (2055000.0 + 0.412);
  
  for (a=1;a<100;a++)
  {
    Serial.print("aaa=");
    Serial.println(aaa,7);
    aaa = aaa + .01;
  }
  
}

Outputs:
aaa=2055000.37500
aaa=2055000.37500
aaa=2055000.37500
etc

Why is this code unable to add to a float properly?
I’ve read that precision only bunks out at 7 or 8 places.
Ideas most welcome.

Yes, six or seven places is about all you'll manage.
2055000 accounts for seven.

32.32 fixed point using a long long could help you.

So you are saying that the integer part positions can occupy the floating point positions?
I've not seen this kind of behavior before.

I'm not sure I understand your question, but the important part of "floating point" is the "floating" part of the name.

j514:
So you are saying that the integer part positions can occupy the floating point positions?

That's the definition of floating point. The decimal point can "float" throughout the number, it doesn't matter which side of the decimal the significant figures happen to be on.

j514:
I've not seen this kind of behavior before.

You probably have seen this behavior before and not realized. On other platforms the floating point data type might be large enough that you didn't run into this "issue."

j514:
I've read that precision only bunks out at 7 or 8 places.

Indeed, and you don't get two lots of precision: one before the decimal point and one after.

A 32-bit float will typically have 23 bits of mantissa, 8 bits of exponent, and 1 for the sign. Thus the biggest number you could store in the mantissa would be 2^23 (8,388,608). Note that there is a bit more to it than that, read the article. However as you can see that is roughly 7 digits. Then with 8 bits of exponent you get an exponent of -126 to +127 (a number of all 1's is reserved for NaN).

So the exponent basically tells the "computer" how many places, left or right, the decimal point is.

On other platforms the floating point data type might be large enough that you didn't run into this "issue."

I think that's the case. I looked up the long long data type but didn't find any useful examples. How do I manage a floating point within this data type and display the variable in a Serial.print statement? I tried this without improvement:

long MILLION = 1000000;

  aaa = 2055000 * MILLION;
  aaa = aaa + (0.412 * MILLION);

You don't do floating point in a long long, you do fixed point.
See reply #1.
Perhaps if you told us what you're trying to achieve, we could help more.

You don't do floating point in a long long, you do fixed point.

Yes I’m aware of that, thus the use of MILLION.

void loop()
{
unsigned long long int aaa;
int a;
long MILLION = 1000000;

  aaa = 2055000 * MILLION;
  aaa = aaa + (0.412 * MILLION);
  
  for (a=1;a<100;a++)
  {
    Serial.print("aaa=");
    Serial.println((unsigned long long int) aaa); // no idea how this should be cast
    aaa = aaa + 10000;//(.01 * MILLION);
  } 
}

edit: (.01 * MILLION) was shown incorrectly as 1000, corrected to 10000

Okay I’m lost.
Are there any examples of how I might go about doing this?

As AWOL already said, if you told us what you are trying to achieve (end result, not some arbitrary test code) we could probably provide more help.

A quick google on 'fixed point math' will provide a variety of links covering the basic concepts of fixed point math.

What does your output look like? (Sorry, I'm posting from my tablet, and I'm a long way from my Arduinos)

It looks like this:

aaa=2006054544
aaa=2006064544
aaa=2006074544
aaa=2006084544
aaa=2006094544
aaa=2006104544
aaa=2006114544
aaa=2006124544
aaa=2006134544
aaa=2006144544
aaa=2006154544
aaa=2006164544
aaa=2006174544
aaa=2006184544
aaa=2006194544

So it goes up 10000 each time. Now, long long takes a great deal of machine code (to add up 8 bytes to 8 bytes, for example, takes a lot of machine instructions).

What are you really trying to achieve here?

As AWOL already said, if you told us what you are trying to achieve (end result, not some arbitrary test code) we could probably provide more help.

More or less the same thing being done at:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=printview&t=105108&start=0

What does your output look like?

Like a float whose decimal points were truncated.

I was able to get around the issue by separating the decimal part into a float value and the integer part into a long.
A side issue though - how does one display a 64 bit value in Serial.print ?

j514:
I was able to get around the issue by separating the decimal part into a float value and the integer part into a long.
A side issue though - how does one display a 64 bit value in Serial.print ?

You can't use Serial.print as-is to print a 64-bit value. The largest value that Arduino supports is a float which is 4 bytes. That's 32 bits.

math.h has 20-digit defines. Maybe math.h handles 64-bit variables?

To people 'at home' in their PC, embedded computing must be like waking up a tent. There is no running hot water or flush toilet and no place to plug in the hair dryer. But they keep looking around at rocks and trees as if there must be a socket somewhere.

there must be a socket somewhere

Indeed! But I will digress to shifting bits if necessary.

This is working well now, thanks to all who responded !

J