## troubles during incrementing floating point variable

4 posts / 0 new
Author
Message

Hey,

I am having some troubles with floating point type. I need to increment a simple FLOAT variable from initially -1.0 up to +1.0 in steps of 0.1 and start thereafter with -1.0 again in a loop.

During debugging I recognized that the content of the variable behaves like: -0.9, -0.8 and then -0.699999 instead of -0.7, and so on. It happens on the real AVR as well as on the simulator. I am using Atmel Studio 7.0 and set the Compiler Optimization Level option to NONE (-O0), Debug Level option MAXIMUM (-g3).

Is there something wrong with my project properties (compiler, debugger etc.).

Many thanks,

Stephan

Sounds like normal operation with floating point. Wikipedia has a page on ieee754. This will shed some light on how floating point operates. If you want precision, use integers.

In decimal try to express 1/3 *exactly" as a decimal fraction.

(having problems? Thought so!)

Now realise that in binary fractions the number 1/10 cannot be represented for the same reason (it's an infinitely recurring binary fraction).

So just as when you add 0.3333 + 0.3333 + 0.3333 in decimal and don't quite get back to 1.0 so it is if you try to add 1/10 + 1/10 + 1/10 + ..  in binary you cannot get back to 1.0

If you go to an online IEEE754 converter such as this:

https://www.h-schmidt.net/FloatC...

and try to represent 0.1 you will see:

00111101110011001100110011001101

If you split that into sign, exponent and mantissa it is:

0 01111011 10011001100110011001101

So the mantissa is:

10011001100110011001101

All normalised binary fractions in IEEE754 have an implied leading zero so this is really:

1.10011001100110011001101

but it does not stop there. This is a recurring binary fraction (like 0.333333333333333333333333333333333333333....... is a recurring decimal fraction) so it is really:

1.1001100110011001100110011001100110011001100110011001100110011001100110011.........(and on to infinity as Buzz Lightyear might have said!)

if allowed to that would go on forever. But it cannot - so in 23 bits it is rounded up to:

1.10011001100110011001101

And THAT is why you cannot add a load of decimal 0.1's and ever hope to get back to 1.0 ;-)

There are number representation systems in computers that can represent decimal accurately (BCD or IBM's "decimal lib" for examples) and if you were running Santander or HSBC you would be using such things as all those lost 0.00000000001's add up and someone is bound to notice eventually. But for "float" in C you generally have IEEE754 and it's a binary representation system.