# 2 < 2 = true ??????

Hi all,

I’m having a very strange issue in C#. I have a Vector2 named position and a Vector3 named _playerPosition. I’m comparing their y values within an update function to check if I should move the player. The weird thing is I have a glitch in the movement because the conditional keeps reporting as true when it shouldn’t. For example, position.y = 2, _playerPosition.y = 2, yet position.y < _playerPosition.y keeps resolving as true. How is this possible?

``````...

if(position.y < _playerPosition.y)
{
print("decreasing y: "+ position.y +" < "+ _playerPosition.y +" = "+ (position.y < _playerPosition.y));

velocity.y -= speed;

if(velocity.y < -1.0f)
{
velocity.y = -1.0f;
}
}

...
``````

The print statement reads: `decreasing y: 2 < 2 = True`

Any ideas why this conditional is not executing properly?

I think you are possibly a victim of floatiness, can you output the actual values?

For sufficiently large values of 2.

print will truncate floating point values, which is why they both appear to be exactly 2. In truth one is probably very slightly larger than the other. You should use an approximate comparison, such as

``````// Test if position.y is significantly less than playerPosition.y
if(_playerPosition.y - position.y > 0.01f) {
}
``````

I traced out the vectors and it shows like this:

``````decreasing y: (1.0, 2.0) < (0.0, 2.0) = True
``````

I tried pixel’s solution but it didn’t work either. I’m thoroughly confused.

Oh and just to correct my first post, _playerPosition is a Vector2 not Vector3.

Use String.Format to display a decent number of significant digits. You’ll still have a float so the imprecision will still be there, but at the very least, you’ll get an idea of the actual value your float contains.

Assuming your not using complex properties with those two vector2’s. A simple way to test this would be to change your code like this

``````...

if(position.y < _playerPosition.y)
{
[COLOR="red"]if( position.y == _playerPosition.y ) print("DANGER WILL ROBINSON");[/COLOR]

velocity.y -= speed;

if(velocity.y < -1.0f)
{
velocity.y = -1.0f;
}
}
``````

And that print line should never be printed ever.

From looking at the snippet of code ( and this is really a shot in the dark ) i think that your setting the velocity the wrong way, where that if is changing the velocity so rapidly every frame that it gets down to really small fractions. Try negating your y velocity. Also it looks like your treating speed like its suppose to be a acceleration? try changing the ‘-= speed’ line to ‘-= speed * Time.deltaTime’

Hi,

have a look here : Unity - Scripting API: Mathf.Epsilon
and here Unity - Scripting API: Mathf.Approximately

Thanks for the help folks, but I’m still getting inconsistent results.

I’m going to move on for the time being and come back to this problem later.

I’ll let you know if I find a solution.

Cheers,

Ok, just after saying that I thought of a completely different approach to the algorithm. Once implemented, my problem disappeared.

I was able to clean the function up and reduce it from 70 lines of code to 20. A lot of that code was if statements doing floating point comparisons. Now, I’m just using a couple of functions from the Mathf library.

So I guess the lesson here would be you can’t completely trust floating point comparisons, especially when they’re being used in sloppy pieces of code

you can’t ever compare floats or expect print libraries to show them properly either. It’s the nature of the beast with computers.

Just to be clear (and I’m sure this is what hippocoder meant): You should never compare floats for equality. Obviously, they can be compared in all kinds of other ways.

What about if I make a statement like this?

``````if(vector1 == vector2)
``````

I’m assuming the Vector classes would deal with precision properly, like using Mathf.Approximately or something along those lines.

I believe operator == is overloaded for Vector2 and Vector3 to compare their components, which happen to be floats, so precision would be the same as with floats.

That’s definitely implementation dependent and will vary based on different math/graphics libraries. However, concerning Unity’s Vector3 class specifically, the docs say this:

Returns true if the vectors are equal.
This will also return true for vectors that are really close to being equal.

So, yeah, there is some fudge factor there, though it’s not specifically defined.

Hi again…

did one of you have read my previous post

For floats comparisons, look in the documentation at Mathf.Epsilon and Matf.Approximately