Comments and answers for "Unity 2*10^-16 == 0 is true!!"
http://answers.unity.com/questions/1587222/unity-210-16-0-is-true2e-16-0-is-true.html
The latest comments and answers for the question "Unity 2*10^-16 == 0 is true!!"Comment by troien on troien's comment
http://answers.unity.com/comments/1587265/view.html
Ok, so to better explain my answer :)
----------
> Either the engine is having issues
> comparing such tiny numbers and that,
> in this case, 2*10^(-16) == 0
This is not as much with the Unity engine, it is more a problem with floating points in general (Follow the link to the floating point inaccuracies in my original answer, explained pretty good there, point 3 in that accepted answer is probably the problem you are facing atm.), which is why the engine has certain helper methods (like Mathf.Approximate and the Vector3 == Vector3 operator) to make sure you can still do equal checks, even though after manipulation the float values are not 100% equal.
Meaning that unity made these method return true on purpose, even though they are actually not equal, they are equal enough, in case of [Vector3][1]:
> To allow for floating point inaccuracies, the two vectors are considered equal if the magnitude of their difference is less than 1e-5.
----------
What I think is happening is that in this 'duplication of vectors' some maths are involved without realizing it (Maybe scale or conversion from local to world when you retrieve it from a transform) Meaning the duplicated values have a chance that the are not exactly the value you expect them to be. I always believed that just copying them should not change their value ever, but I'm not 100% sure on that one and I don't know where you copy them from/to and how you copy them. As getting or setting transform.position will probably involve maths.
As a general rule, I just never expect any floats to be an exact value.
----------
Looking at the things you figured out I expect that the IEnumerable.Distinct is implemented to use .Equals instead of the .== operator, meaning it won't see the 0 and 2*10^-16 as equal and include them both. Maybe an easy fix would be to write your own Distinct and use the .== operator in there? Because properly 'fixing' float inaccuracy is impossible. And in most cases it doesn't matter because the difference is so small that you can't notice it.
----------
Also, it shouldn't be a problem with just 0 and not just y, more numbers and axis can suffer from this, and to make it even more fun, 2 different machines can get 2 different results...
[1]: https://docs.unity3d.com/ScriptReference/Vector3-operator_eq.htmlSun, 06 Jan 2019 14:38:23 GMTtroienComment by margual56 on margual56's answer
http://answers.unity.com/comments/1587258/view.html
I'm sorry I didn't make myself clear, it's a bit complicated and I don't really know the exact source of the problem:
- I create a List containing Vector3
- Those Vector3 have the y = 0
- _**I don't operate or manipulate them any further!**_
- Some of those vectors are duplicated, so I use the "Distinct()" function to try to eliminate them
- When I spawn an instance at those positions one of the instances will have y = 0 and the duplicate, y = 2*10^-16
- Then, I placed an if statement before the "Instantiate":
> if(y == 0){Instantiate(...);}
to try to eliminate the duplicates with y = 2*10^-16
- I hit play and there were the same duplicates, with y = 2*10^-16
----------
*(I already tried looping through all the vectors and setting their y to 0)*
----------
Therefore, I deduce that:
- Either the engine is having issues comparing such tiny numbers and that, in this case, 2*10^(-16) == 0
- Or the Instantiate function is having some issues with the coordinate y = 0
_(Although I doubt it is the second option because otherwise, the "Distinct()" function would have eliminated the duplicates. So we can say there's a difference between the Vector3, which in the editor appears to be the y component)_
----------
So, what I want is to eliminate those duplicated vectors and the only difference they have in the editor (after exectution) is the y component.Sun, 06 Jan 2019 13:44:44 GMTmargual56Answer by troien
http://answers.unity.com/answers/1587227/view.html
I'm honestly not 100% sure what you want to do, because to me it sounds like you actually want to use the Approximatly() method in parts of your question, but then you state you want the opposite... So here are the options you have.
So, if you want to check if two vectors are exactly equal, you can use:
- Vector3.[Equals][1].
If you want to check if 2 vectors are practically equal. But might have very slight differences due to [floating point inaccuracies][2]. (This was the first google hit for me, google it yourself if it isn't clear enough)
- Vector3.[== operator][3] (see link for example of what is considered equal)
If you are instead of comparing vectors, comparing individual floats, you can use Mathf.[Approximately][4] to compensate for float inaccuracies.
[1]: https://docs.unity3d.com/ScriptReference/Vector3.Equals.html
[2]: https://stackoverflow.com/questions/2100490/floating-point-inaccuracy-examples
[3]: https://docs.unity3d.com/ScriptReference/Vector3-operator_eq.html
[4]: https://docs.unity3d.com/ScriptReference/Mathf.Approximately.htmlSun, 06 Jan 2019 11:39:20 GMTtroien