#what are you trying to do big picture

1 messages · Page 1 of 1 (latest)

pure plume
#

I'm trying to find out why the output of rect.xMax contains an error. One that cannot be reproduced with rect.x and rect.width.

Do not be distracted by the promise of offering me an easy answer that has nothing to do with my question.

There is a saying, "look after the pennies and the pounds look after themselves".
Here a penny has gone missing.
Where did it go?

it may not be just rect.xMax that is affected. That is why the question is important to ask.

slate flax
#

gotchya!

#

lol

pure plume
#

I am already capable of solving the issue this creates.

But the fact that this is a feature of Unity - of certain getter setters returning unexpected values. How deep does the rabbit hole go?

slate flax
#

i think i gotchya

#

i get the medal right?

#

you have to tell me what you are trying to do, or you can recede into the abyss

#

who knows what we'll discover together

#

on this journey into What You Are Really Trying to Do

#

the Y of your XY Problem

pure plume
#

rect.xMax returns a different result to rect.x + rect.width.

But looking at the source code for Rect suggests that rect.x + rect.width is what is actually returned.

So what happened in between?

slate flax
#

what are you trying to do

#

what is the y of your xy problem

pure plume
#

To solve the mystery of why rect.xMax's behaviour.

I can create a workaround very easily because I can apply an epsilon to rect.x + rect.width to create similar behaviour.

But that does not answer my question.

slate flax
#

what is the context where this bug came up?

pure plume
#

I was testing a rect overlapping an interval.

I was applying an epsilon to that test in order not to get a false positive.

But I also found that I could use rect.xMax and an epsilon was applied out of nowhere. I didn't need to add an epsilon - I could just confuse the shit out of anyone else reading the code.

Neither the docs or the source code answers this mystery. And so I have come here.

slate flax
#

can you show me how you are doing this

I was testing a rect overlapping an interval.

#

what is the function that does this? what is the code?

pure plume
#
public List<Block> GetBlocksIn(Rect area, Block ignoreBlock = null, Flag flag = Flag.Everything, Flag ignore = 0)
{
    // Issues:
    // Block.Tolerance is subtracted to avoid a false positive
    // used to subtract Block.Tolerance on all direction but that fails when performing precise steps back and forth
    // discovered that rect.xMax produces a satisfactory error that avoids overlaps but it makes for bad code

    var result = new List<Block>();
    for(int i = 0; i < blocks.Count; i++)
    {

        var b = blocks[i];
        if(
            b != ignoreBlock &&
            (b.flag & flag) != 0 &&
            (b.flag & ignore) == 0 &&
            b.x + b.width > area.x &&
            area.x + area.width - Block.Tolerance > b.x &&
            b.y + b.height > area.y &&
            area.y + area.height - Block.Tolerance > b.y
        )
        {
            result.Add(b);
        }
    }
    return result;
}```

Here is the the function that led to this discovery.

The big picture is that rect.xMax exhbits strange behaviour.

That's the problem I want to solve. I want to be able to use Unity functions and know in advance if they are going to contain floating point errors of such a size that they affect my engine.

I don't want a workaround. I want to know the cause.
#

If you'd like to test this example yourself:

var rect = new Rect(20.2f, 0f, 0.8f, 1f);
var x = 20.2f;
var width = 0.8f;
var xMax = rect.xMax;
UnityEngine.Debug.Log(width + x == rect.xMax);// false
UnityEngine.Debug.Log(rect.width + rect.x == rect.xMax);// false
UnityEngine.Debug.Log(rect.xMax == xMax);// true```
Note the last example - this proves that the error can be stored and it is not localised to Debug.Log
steep yacht
slate flax
#

the cause is really simple, it's a floating point limitation

#

I don't want a workaround. I want to know the cause.
the cause is when you declare a value as a string like "20.2f" it cannot be represented exactly in floating point

#

here you go

pure plume
#

@slate flax rect.xMax does not equal 21.0f

At no point have I posted code testing for 21.0f - you have invented this yourself.

In fact you have gone as far as to assume that rect.xMax creates 21.0f out of nowhere, even though internally it's source code says it is being created from it's "x" and "width" properties - which I have set in my code to 20.2f and 0.8f respectively.

And yet when I test floating point values adding 20.2f + 0.8f I can get the same result every time - except when that result comes from rect.xMax.

I am already aware that 20.2f + 0.8f produces a floating point error.

What is significant is that rect.xMax produces a completely different floating point error.

Given that this is a feature of Unity, it is important to know if it is unique to this one method or if many other internal classes exhibit the same behaviour.

slate flax
# pure plume <@247793168056057857> rect.xMax does not equal 21.0f At no point have I posted...

i was going off of

// Magic floating point error example
var rect = new Rect(20.2f, 0f, 0.8f, 1f);
var x = 20.2f;
var width = 0.8f;
var xMax = rect.xMax;
UnityEngine.Debug.Log(width + x == rect.xMax);// false
UnityEngine.Debug.Log(rect.width + rect.x == rect.xMax);// false
UnityEngine.Debug.Log(rect.xMax == xMax);// true

here, x + width == 21.0f is false, does that make sense?

#

rect.xMax produces a completely different floating point error
i'm saying it's the same kind of floating point error

#

you're welcome to write your own rect and see the same error

#

that's what i tried