Adding to float gives inaccurate results?
Monkey Forums/Monkey Programming/Adding to float gives inaccurate results?
| ||
I have declared a float... Global gasSale:Float = 0.0 In my update loop under certain circumstances, I will increment this variable like this... gasSale += 0.4 or like this... gasSale = gasSale + 0.4 Both giving the result of this in the first iteration... 0.40000000596046448 Is this common core math? Lol, jk, but am I missing something? |
| ||
Is this common core math? Yes, Float is never precise. This is not only true for Monkey X but for every other language too. The tiny value differences are most of the time irrelavant except for networking and fast cycles that could go crazy. You only need to be careful with = because it might not work as expected. |
| ||
lol, ok I've read about it before in other languages, but never ran into it so blatantly like this. What I don't understand is how adding 0.4 can lead to this though since it shouldn't be rounding or leading to an excessively long float requiring some kind of rounding. So would a double type lead to this kind of inaccuracy? Thanks for the info. I'll see what kind of work around I can use. Thanks! |
| ||
Wow, testing this in Java produced these results... tFloat = (float) (tFloat + 0.4); tDbl = tDbl + 0.4; System.out.println("tFloat: "+tFloat); System.out.println("tDbl: "+tDbl); Starting game... tFloat: 0.4 tDbl: 0.4 tFloat: 0.8 tDbl: 0.8 tFloat: 1.2 tDbl: 1.2000000000000002 tFloat: 1.6 tDbl: 1.6 tFloat: 2.0 tDbl: 2.0 tFloat: 2.4 tDbl: 2.4 tFloat: 2.8000002 tDbl: 2.8 tFloat: 3.2000003 So it seems that both data types produce inaccurate returns. I get the same results using Float in MonkeyX since double is not available. This is hard for me to understand why something so simple can lead to these kinds of outcomes. |
| ||
That's how floats are. They have two parts, a binary part that represents a number, and an exponent that it is multiplied by. Not all numbers can be represented, just a sample of values which get further apart as the value increases. Doubles use 64 bits instead of 32, so they are much more accurate. They put some of the extra bits into storing the exponent, so they have a wider range too. But no matter how big the float is, the issue will always be there. In the old days, people were taught never to treat floats as exact, and always use integers when exact numbers are required. For example, if you were writing code to take account of currency in a bank, you would use a long integer to track every cent. And you would never simply test equality between two floats. I think people do the latter now because it seems to work for smallish integers. But down the line it can cause problems. Your 0.4 is not all that inaccurate; it is correct to better than one part in ten million. |
| ||
Thanks for the input! I really did quite a bit of reading. I've always heard about the inaccuracy but never ran into it, of course I'm getting old and can't really remember if I intentionally stayed away from floats or not over the past 10 years. I believe I normally used ints. I just can't grasp that just adding 4 tenths to a number can cause these kinds of numbers to jump around. Its just... weird for such a small number. Thanks again! |
| ||
Welcome to the wonderful world of signs, exponents, mantissas and values. |