Crazy Floating Point Inaccuracy Contradicting Itself

Now i am aware the bug is specific to my particular project so i am not sure you'll be able to replicate it, and right now i wouldn't be able to provide all of the code for the project so you could see it, and even so i don't think a solution can be provided. However i got a weird instance of floating point inaccuracy, maybe you guys have a tip or suggestion or something to say about it.

First up I am comparing Vector Right and Vector Forward of an object to decide a limited number of object facings that I want, its relevant down the line to art style uv and lighting efficiency.

``````            if (RIGHT.x < 0 && RIGHT.z < 0)
{
if (FORWARD.x > 0 && RIGHT.z < 0)
{
UPHILL = 1;
Debug.Log("WHY THIS" + RIGHT.x + " " + RIGHT.z + " " + RIGHT);
}
}
``````

The result returned is contradictive == WHY THIS -1.117587E-07 -1 (0.00, 0.00, -1.00)

Its telling me 0.00 = -1.117587E-07 on the X; So a request for Right gives me 0, 0, -1, but a specific request for Right.x gives me -1.117587E-07.

I don't know how to write -1.117587E-07 in code and have it be read and recognized that this result is same as zero and as you can see the full debug of vector RIGHT returns 0.00, 0.00 -1.00

We are correct on the Z of -1, but that X is just a straight up floating point failure.

Well what's happening? I suspect voltage is leaking into it. And its registering a microscopic value, and this would be something going on in the microchip. I am not able to ask for the int in this case simply because sometimes my right is at a 45 degree angle or diagonal or pitch and yaw, and so both return a value that is needed for example a right of 0.21, 0, -0.21 may be needed. In which case the int would cause further bugs or inability to check those values and run logic.

I'm not angry or anything, I have become much more enlightened and calm as I improve, and I think I can figure this out if I think about it. But I am aware there are a bunch of smart people on the forum so I just thought I'd flag occurrence of it in the public and see what if anything you would do without stringing this number to string. Or do you suspect this is a rare instance where string is the only way to read this number.

Anyways

Hope I wrote clearly it enough. Let me know what you think.

This is just an issue of the default string formatting for Vector3 only showing 1-2 decimal points. This is not some freak microchip failiure. Try this:

``````Debug.Log("Better formatting: " + RIGHT.x.ToString("F12") + " " + RIGHT.z.ToString("F12") + " " + RIGHT.ToString("F12"));
``````

The code shouldnâ€™t even be entered as RIGHT.x = 0.

So I have to make a string and compare strings instead of Vector floats?

``````            if (RIGHT.x < 0 && RIGHT.z < 0)
{
if (FORWARD.x > 0 && RIGHT.z < 0)
{
UPHILL = 1;
Debug.Log("WHY THIS" + RIGHT.x + " " + RIGHT.z + " " + RIGHT);
}
}
``````

No you donâ€™t need to do string comparisons. You said it yourself RIGHT.x is NOT 0, it is -1.117587E-07, which is a very small negative number.

A trick if I grab the very small negative number and check if right.x + very small negative number is still less than 0 then we can run the logic.

hmm

I need to log and keep in memory the very small negative number and call it FloatingPointBug and then check 0 + floatingpointbug to see if its still less than zero :S

Public static constant FloatingPointBug

Yah i can write

``````static float FLOATINGBUG = -1.117587E-07f;
``````
``````           else if (RIGHT.x - FLOATINGBUG < 0 && RIGHT.z < 0)
{
if (FORWARD.x > 0 && RIGHT.z < 0)
{
UPHILL = 1;
Debug.Log("WHY THIS" + RIGHT.x + " " + RIGHT.z + " " + RIGHT);
}
}
``````

Itâ€™s not a bug. -1.117587E-07f is zero with floating point precision. You might consider https://docs.unity3d.com/ScriptReference/Mathf.Approximately.html

1 Like

Thatâ€™ll be the ticket

For the record you canâ€™t subtract this though I did test it.

Mathf.Approx will work fine I am sure of it

Thank you

1 Like

It didnt actually work. However i am abit of a dummy

So now i am

``````using System;
``````
``````Math.Round(RIGHT.x, 2)
``````

or better yet

``````RIGHT = new Vector3((float)Math.Round(RIGHT.x, 2), (float)Math.Round(RIGHT.y, 2), (float)Math.Round(RIGHT.z, 2));
``````

This whole thread is a little bit of an XY problem to be honest. If you want the best answer for how to accomplish your goals, you should explain what exactly youâ€™re trying to accomplish here.

https://xyproblem.info/

What the heck is that? Looks like no code Iâ€™ve seen ever to compare floats. I think like others have said - please state your actual use case rather than trying to make your non-working solution, work as likely there are a lot of solutions in this space.

Good Question, by the way I am sorry about winding you up before. I didnâ€™t mean to seem so crazy.

But Good Question!!!

GOOD QUESTION INDEED

Now the unit is moving very slow while i check the angles, He does move much faster.

1 Like

So the Unity Vector3 position is a Double not a float so we Float the double and then round the float of the double.

I think I got it under control.

The Unity Vector3 position is a float, but Debug Log or print will truncate the number when printing it out, unless you print out the individual x, y or z elements. Is this what you were referring to? System.Math probably uses doubles though.

1 Like

My mistake the return is the double but itâ€™s rounded to the specified decimal and converted to float for unity

the odd part was, and the reason for the thread is that 90% of the code functioned correctly and was able to successfully detect a negative or positive, only a small minority of directions started to require rounding. So I had actually written 95% of the required code before I found that the floating point inaccuracy was present. It will be useful for the future in comparing vectors. The other method posted returned a bool true or false and so couldnâ€™t be used on a > greater than or less than < check.

1 Like