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.

Here i ask

            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 :smile:

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
:stuck_out_tongue:

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

https://www.youtube.com/watch?v=yTVOEmV6i8Q

1 Like

So the Unity Vector3 position is a Double not a float :slight_smile: 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