#what are you trying to do big picture
1 messages · Page 1 of 1 (latest)
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.
well there is an easy answer, you can create your own rect class and have it do whatever you want, that's why i'm asking you for a big picture perspecitve on what you are actually trying to do
gotchya!
lol
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?
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
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?
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.
what is the context where this bug came up?
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.
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?
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
hate to be that guy, but you’re asking for the X of his XY problem
okay... but 20.2f + 0.8f == 21.0f is false, so this isn't a bug with Rect
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
@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.
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