Possible Duplicate:
Floating point equality in python
I have a small "issue" about my Python code (I use version 2.5 right now, in ika game engine). I currently script objects for my game, and i would like to know, if its safe to compare two floating point number This way:
I will make a short example of what I do currently.
Every objects has a speed, from 0-9, represented in floating points. For example
speed = 4.83
cord_x = 10.0
cord_y = 10.0
They have an AddMovement method. This sets an X,Y value, and represents the goal coordinates for the object.
target_x = 25.0
target_x = 26.75
movement = True # This represents if the object is moveing or not
Every frame, the Maximum speed equals to this value:
maximum_x_speed = abs(cord_x-target_x)
maximum_y_speed = abs(cord_y-target_y)
And the real speed will be:
# Get the real X speed in this frame
if maximum_x_speed < speed:
real_x_speed = maximum_x_speed
else:
real_x_speed = speed
# Get the real Y speed in this frame
if maximum_y_speed < speed:
real_y_speed = maximum_y_speed
else:
real_y_speed = speed
Now, based on this real_x_speed value, and real_y_speed value, i substract this value from the coordinates.
if target_x < cord_x:
cord_x -= real_x_speed
elif target_x > cord_x:
cord_x += real_x_speed
if target_y < cord_y:
cord_y -= real_y_speed
elif target_y > cord_y:
cord_y += real_y_speed
And at the end, i check for equality
if cord_x == target_x and cord_y == target_y:
# Halt movement, reached goal
movement = False
I had floating point errors in the past, with the 0.1 issue, and like... I fear, that this will cause some kind of error. Or this is logically impossible?
If i had grammar mistakes, sorry for them. english is not my native language... I would really appreciate some tips, if i should change this logic, or not.
A format of . 2f (note the f ) means to display the number with two digits after the decimal point. So the number 1 would display as 1.00 and the number 1.5555 would display as 1.56 . A program can also specify a field width character: x = 0.1.
The floating-point calculations are inaccurate because mainly the rationals are approximating that cannot be represented finitely in base 2 and in general they are approximating numbers which may not be representable in finitely many digits in any base.
Floating-point decimal values generally do not have an exact binary representation. This is a side effect of how the CPU represents floating point data. For this reason, you may experience some loss of precision, and some floating-point operations may produce unexpected results.
No, this type of code is never a good idea.
There will be floating point errors that accumulate, making it very hard to track. You really should use an "epsilon" approach, i.e. consider the two values equal if the difference is smaller than some set constant, which is often called epsilon:
def floats_equal(x, y, epsilon = 1e-4):
return abs(x - y) < epsilon
Of course you must tweak the epsilon
value as required for your application, but a game where the values represent pixel-based locations shouldn't need too much precision.
Note that, as also pointed out in other answers, there is a smallest epsilon that will work on the machine, but often you are better off using an application-level epsilon, such as the one above. When interpolating things in 2D pixel space for presentational purposes, there's seldom any point in precision in on the order of 2.22044604925 * 10-16, which happens to be the value of sys.float_info.epsilon
on my local system.
It is usually better to do this this way:
EPSILON = 0.00001 # or whatever
if abs(cord_x - target_x) < EPSILON and abs(cord_y - target_y) < EPSILON:
# Halt movement, reached goal
movement = False
Some people choose EPSILON
to be:
import sys
sys.float_info.epsilon
Which is the difference between 1 and the least value greater than 1 that is representable as a float - here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With