Software Software
asked on
Float variable freezes after increasing
I know, that it isn't a good way to increase a float variable inside a loop. But thats not the point.
And I know that most float numbers can't exactly convert to a binary number.
Can someone explain to me detailed the behaviour on case 1 and 2?
1) Why do the counters diverge?
2) Why does the second counter freeze after some time (I get after some time the same number even though I increase floatCtr by 0.1)?
And I know that most float numbers can't exactly convert to a binary number.
Can someone explain to me detailed the behaviour on case 1 and 2?
1) Why do the counters diverge?
2) Why does the second counter freeze after some time (I get after some time the same number even though I increase floatCtr by 0.1)?
int main()
{
uint32_t uint32Ctr=0;
float floatCtr=0;
for(;uint32Ctr<=100000000;uint32Ctr++){
floatCtr+=0.1;
if(uint32Ctr%10000==0){
printf("uint32 Counter = %d\t float Counter = %f\n", uint32Ctr, floatCtr);
}
}
return 0;
}
What is the number that is displayed when it freezes? You can reach a point where '0.1' is below the resolution of the floating point number so it is essentially 0. Is this 32-bit or 64-bit floating point?
Floating point numbers can be thought of as a value times an exponent. If this was base 10, the value for 256 might be represented as 2.56 x 10^2.
So since floating point values in computers have limited precision, imagine a simple case where you only get 2 decimal places in the floating point value:
e.g. 256.0 = 2.56 x 10^2
The 2 decimal places here refers to in 2.56 - there's limited precision to this expression.
But when you add 0.1 to it you get 256.1, which is still 2.56 x 10^2 - i.e. there's no difference between 256.0 and 256.1 (if floats only allowed 2 decimal places in their internal representations). That's because they both encode to 2.56 (to 2 dp).
In other words the value would appear to freeze as you added a small number to it (0.1).
In reality, a floating point value is in binary but it's the same basic structure (a number to a certain amount of precision times an exponent). So eventually when you add a small number to it, there's no change in the value.
I hope that makes sense.
So since floating point values in computers have limited precision, imagine a simple case where you only get 2 decimal places in the floating point value:
e.g. 256.0 = 2.56 x 10^2
The 2 decimal places here refers to in 2.56 - there's limited precision to this expression.
But when you add 0.1 to it you get 256.1, which is still 2.56 x 10^2 - i.e. there's no difference between 256.0 and 256.1 (if floats only allowed 2 decimal places in their internal representations). That's because they both encode to 2.56 (to 2 dp).
In other words the value would appear to freeze as you added a small number to it (0.1).
In reality, a floating point value is in binary but it's the same basic structure (a number to a certain amount of precision times an exponent). So eventually when you add a small number to it, there's no change in the value.
I hope that makes sense.
ASKER
@Dave Baldwin
If you run the program, the number that is displayed when it freezes is 2097152.000000
This is a 4 Byte (32-bit) floating point.
@dpearson
I don't think that's the exact correct answer.
It has something to do that all decimal places go by the board when you slide to the right.
But I don't understand it really.
If you run the program, the number that is displayed when it freezes is 2097152.000000
This is a 4 Byte (32-bit) floating point.
@dpearson
I don't think that's the exact correct answer.
It has something to do that all decimal places go by the board when you slide to the right.
But I don't understand it really.
@dpearson gave you the right answer. Floating point numbers have a limited range and precision and your experiment is exceeding the precision that is available. This page may help. https://www.cs.yale.edu/homes/aspnes/pinewiki/C(2f)FloatingPoint.html
It has something to do that all decimal places go by the board when you slide to the right.That is indeed a potential problem with decimals, but I don't think it's happening here because nothing is being shifted to the right - which is a form of division.
e.g. 2 >> 1 means "2 shifted 1 position right" which is the same as "divided by 2" (because everything is in binary).
If you divide a floating point number by a value enough times it will get very small and you'll lose precision.
But in your problem you're doing addition rather than bit shifting or division. (And bit shifting floating point values is a pretty complex subject, you'd need to really understand the details of the underlying binary representation, which isn't really necessary for your current problem). If you'd really like to read more about it, there's lots here:
https://en.wikipedia.org/wiki/IEEE_754
but I think that's overkill for your needs (and that page makes my head hurt!)
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
...there's no n for which 2^n is a number, which can be divided by 10 without a remainder.
Can someone explain this to me?if n=1:
2^1=2 -> 2/0.1 = 20 (no remainder)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
due to this it's just not possible to represent decimal values in binary formJust to clarify what Zappo is saying some decimal values can be exactly represented in binary form, while others cannot.
In general, you should not assume that all floating point values can be exactly represented which means eventually that rounding will can cause two mathematically different floating point numbers to end up with the same internal value inside a computer (which is what is happening to you here). That's the key concept to grasp. The details are actually quite complex, but the concept really isn't so bad.