1

Here is the problem:

when VX is some or deduct by 0.05 it deduct/some 0.05000001 (This take part in the Enter-frame, FPS)

        **if(vx < 5 && KR){
            vx += 0.05;
        }else if(vx > 0 && !KR){
            vx -= 0.05;
        }else if(vx < 0 && !KL){
            vx += 0.05;
        }else if(vx < -5 && KL){
            vx -= 0.05;
        }
        if(vy < 5 && KD){
            vy += 0.05;
        }else if(vy > 0 && !KD){
            vy -= 0.05;
        }else if(vx < -5 && KU){
            vy -= 0.05;
        }else if(vx < 0 && !KU){
            vy += 0.05;
        }

1 Answers1

3

Floating point numbers are inherently imprecise - the set of rational numbers is infinite but floating point Number-s are stored on 64 bits, according to the IEEE-754 standard. Obviously, 64 bits is not an infinite number of bits so certain floating point values can be represented exactly and others cannot.

In general, you cannot rely on a floating point number to have the same exact value you're trying to assign to it.

var n:Number = 0.05;

will be translated by the compiler to a floating point representation of 0.05 and that may introduce a rounding error.

When working with floating point numbers, you usually have to use a range around the desired number, instead of checking for exact equality. So instead of doing

if ( n == 0.05 ) // this may or may not fail, based on rounding

you should do something like

if ( ( n > 0.04 ) && ( n < 0.06 ) ) // this will more likely work

The range is up to you - you must decide how much difference is acceptable when you do the check (here I used 0.01). The smaller the range, the more likely you run into rounding errors, though. The larger the range, you'll get more and more imprecise numbers that pass through the check.

Here's a pretty decent article that goes into more detail. The internet also has a lot of resources on how to properly work with floating point numbers.

xxbbcc
  • 15,756
  • 5
  • 42
  • 76