MichaelGofron
MichaelGofron

Reputation: 1400

What is the difference between == and <= in this case

I was working on making a game, and I was wondering why the construct with the == operator doesn't work while the lower one does. I used an NSLog message afterwards to test.

    if (pipe.position.x == bird.position.x){ no idea why this doesn't work
    if ((pipe.position.x <= bird.position.x) & (pipe.position.x > bird.position.x - 1)){

Upvotes: 0

Views: 52

Answers (2)

user2864740
user2864740

Reputation: 61875

This is because one (or both) of the position.x's are a floating-point2 value with a non-zero difference1 between the two position values such that only the second condition is true.

Since p <= b is true for all values that make p == b true, to see why this works "unexpectedly" let's choose some values such that the expression p == b is false2 yet p < b is true and p > b - 1 is true.

Given p = 3.2 (pipe) and b = 3.7 (bird), as an example, then

   p == b
-> 3.2 == 3.7
-> false

but

   (p <= b) & (p > b - 1)
-> (3.2 <= 3.7) & (3.2 > 3.7 - 1)
-> (3.2 <= 3.7) & (3.2 > 2.7)
-> true & true
-> true

Instead, to detect when the bird "is crossing" the pipe, assuming that x increases to the right, consider

   // The bird's head to the "right" of the pipe leading edge..
   bird_x >= pipe_x
   // ..but bird's butt is not to the "right" of the pipe trailing edge.
   // (Also note use of the &&, the logical-AND operator)
&& (bird_x - bird_width <= pipe_x + pipe_width)

Of course, using a non-rectangle (or forgiving overlap) collision detection would lead to less frustrating flapping!


1 This issue occurs because there are some particular floating-point values (but there are no integer values) which can cause the observed effect.

First, reiterate the assumption that p is not equal to b, given that the first condition does not succeed. Let's suppose then that p <= b is written as p == b || p < b but since p == b is false , we can write it as p < b by tautology.

Since both clauses in the second condition are true (such that true && true -> true), we have the rules: 1) p < b is true, and 2) p > b - 1 is true.

Rewriting p < b as p - b < 0 and p > b - 1 as p - b > -1, and then replacing p - b with x yields: x < 0 and x > -1. However, there is no integer value of x which satisfies -1 < x < 0.

(In first section, where p = 3.2 and b = 3.7, x = (p - b) = 0.5 which satisfies the given constraints when x is not restricted to an integer value.)


2 With all above aside, it is possible for p and b to be "very close but different" floating-point values such that there is a non-zero difference between them - due to rounding, they may even be displayed as the same integer value! See How dangerous is it to compare floating point values? and related questions for the cause and "odd" behavior of such when using ==.

If this is the case then round to integer values and use an integer comparison, or; rely entirely on relational comparison such as shown in the proposed condition, or; use epsilon comparison for "nearly equal" of floating-point values.

Upvotes: 3

Sreevidya Aravind
Sreevidya Aravind

Reputation: 433

if you choose abs(pipe.position.x) == abs(bird.position.x) the first condition may satisfy.

Upvotes: 0

Related Questions