240.0 + 0.01 = 240.009995 ???

BlitzMax Forums/BlitzMax Programming/240.0 + 0.01 = 240.009995 ???

wookie(Posted 2011) [#1]
Try this simple program:

print 240.0 + 0.01

and the result is 240.009995



Could someone tell me what am I doing wrong?


H&K(Posted 2011) [#2]
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


H&K(Posted 2011) [#3]
Stupid edit system

Last edited 2011


wookie(Posted 2011) [#4]
Here is another strange example:

Local n# = 0.01
Print n

result: 0.00999999978


GfK(Posted 2011) [#5]
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


Czar Flavius(Posted 2011) [#6]
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!


wookie(Posted 2011) [#7]
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 :)


wookie(Posted 2011) [#8]
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?


Czar Flavius(Posted 2011) [#9]
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


skidracer(Posted 2011) [#10]
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


ImaginaryHuman(Posted 2011) [#11]
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.