Search Unity

Comparing data in Unity

Discussion in 'Scripting' started by SeanKilleen, Mar 4, 2015.

  1. SeanKilleen

    SeanKilleen

    Joined:
    Jul 17, 2013
    Posts:
    6
    Hi All,

    I have a simple enough scenario which is presenting unexpected results.

    I am comparing a float with an int multipled with a float. Both the values are equal to 2 but the if statement doesn't think this is the case.

    Code (CSharp):
    1.     private int leftLane = -1;
    2.     private int centreLane = 0;
    3.     private int rightLane = 1;
    4.     public float laneWidth = 2.0F;
    5.  
    Later on in the function I move an object towards a lane and want to disable input while this is happening.

    Code (CSharp):
    1.     bool IsInLane(){
    2.         var currentLane = transform.position.x;
    3.         if (currentLane == rightLane * laneWidth) {
    4.             return true;
    5.         }
    6.  
    7.         return false;
    8.     }

    upload_2015-3-4_16-45-56.png


    You can see from my Immediate window in the debugger that the function should have returned true?
    Can anyone explain this to me please?
     
  2. jister

    jister

    Joined:
    Oct 9, 2009
    Posts:
    1,749
    you say currentLane = transform.position.x;
    are you snapping this to a grid?
     
    SeanKilleen likes this.
  3. SeanKilleen

    SeanKilleen

    Joined:
    Jul 17, 2013
    Posts:
    6
    No I'm not snapping to a grid. The if statement shoulnd't need to be snapped to anything it should just be comparing two values of type float though?
     
  4. MeltingPoint

    MeltingPoint

    Joined:
    Oct 2, 2012
    Posts:
    1
    I'm going to guess that it's a precision problem. float*int returns a float, which probably isn't an exact number (eg. 1.00000000001) which in your case will fail the comparison. Just a guess.
     
    SeanKilleen likes this.
  5. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,836
    You should (almost) never test whether two floating point numbers are equal. Instead, test whether they are within some threshold of each other.

    So, instead of writing
    Code (CSharp):
    1. float x, y;
    2. // Code
    3. if (x == y)
    use something like
    Code (CSharp):
    1. const float epsilon = 1e-5;
    2. float x, y;
    3. // Code
    4. if (Math.Abs(x-y) < epsilon)
     
    SeanKilleen likes this.
  6. SeanKilleen

    SeanKilleen

    Joined:
    Jul 17, 2013
    Posts:
    6
    So I have replaced my compare statement with
    Mathf.Approximately()
    and it has done the trick.

    The problem here wasn't the fact that I shoulnd't have been comparing two floating point numbers, but the fact that the debugger and the immediate window aren't accurate representations of the floats.

    Thanks for the help folks :)