240.0 + 0.01 = 240.009995 ???
BlitzMax Forums/BlitzMax Programming/240.0 + 0.01 = 240.009995 ???
| ||
Try this simple program: print 240.0 + 0.01 and the result is 240.009995 Could someone tell me what am I doing wrong? |
| ||
Thats the way computers work, Change variable type in the hope of moving the inaccuracy further down the decimals Try doubles if you need it, there is a mod somewhere that exchanges memory of number for accuracy, BUT its bet to try an afford those sort of things speed wise Last edited 2011 |
| ||
Stupid edit system Last edited 2011 |
| ||
Here is another strange example: Local n# = 0.01 Print n result: 0.00999999978 |
| ||
Its not strange, its how computers work and you will get similar results in any language. As already mentioned you could use Doubles instead of Floats but that only lessens the effect - it doesn't eradicate it. Before you say "pah, how much accuracy is needed for 0.01?", try this: Local n:Float Print n Result: 0.00000000000 You'd expect "0", right? A floating point number is always treated as such no matter how big (or small) the variable contents are. If you need 100% accuracy, don't use Floats. Last edited 2011 |
| ||
The inaccuracy looks worse than it is. For example, if you are making a game with physics for a bouncing ball and its mathematically correct speed is 20.4393, but the computer calculates it as 20.4394 instead, this tiny difference will have no noticable effect on your game. 1.000 coming out as 0.9999 looks bad written in our number system, but the difference to your game isn't going to be noticable. It only matters in two cases. First, you are making a super-accurate physics simulation. Second, you are making some kind of maths game. Eg divide these numbers and the player must enter the correct result. In that case, look into arbitrary precision maths library. http://code.google.com/p/maxmods/wiki/MapmModule These kinds of libraries are very SLOW so don't use them for a regular game. Let your ball bounce with the floats! |
| ||
thanks for explaining it Must say that I didn't notice this behavior programming in VB .NET 2005. I will look a this more closely :) |
| ||
Czar Flavius: of course 0.9999 or 1.000 isn't big deal but what when i try to compare these. Will these be equal to blitzmax? |
| ||
It won't. Checking for equality with floats is a big no-no in any language. You can try something like this. The lower the accuracy parameter, the higher the accuracy. This doesn't mean the results will be more correct - if the accuracy in this example is 0.00001 it gives the wrong result as the inaccuracy in the float is detected. Experiment with it. Local a:Float = 240.0, b:Float = 240.0 b = b + 0.01 b = b + 0.01 b = b + 0.01 b = b + 0.01 b = b + 0.01 b = b - 0.05 Print a Print b Print Abs(a-b) If FloatCompare(a, b) Print "Equal" Else Print "Not equal" End If Local c:Double = 240.0, d:Double = 240.0 d = d + 0.01 d = d + 0.01 d = d + 0.01 d = d + 0.01 d = d + 0.01 d = d - 0.05 Print c Print d Print Abs(c-d) If DoubleCompare(c, b) Print "Equal" Else Print "Not equal" End If Function FloatCompare(a:Float, b:Float, accuracy:Float = 0.0001) Return Abs(a-b) <= accuracy End Function Function DoubleCompare(a:Double, b:Double, accuracy:Double = 0.0001:Double) Return Abs(a-b) <= accuracy End Function Last edited 2011 |
| ||
Or to put it another way, floats are imperial not metric. Consider using integer when designing metric system where the smallest value 1 represents the smallest unit in a calculation such as millimieters or microseconds. Or change all your print statements to uses a human readable rounded version of a float. The reason BlitzMax produces such unrounded output is that when that format is read back from storage it will always match that exact negative power of 2 representation that are the bits in the computers internal registers. Last edited 2011 |
| ||
Could someone make a really obvious sticky post which says clearly, float point numbers do not store accurate numbers, cus this has been asked a hundred times. |