Imprecise results when using go.Rect.unionRect()


I am using the go.Rect.unionRect function to create a Rect for multiple GraphObjects:

let allBounds: go.Rect;
graphObjects.each(panel => {
  let bounds = new go.Rect(panel.getDocumentPoint(go.Spot.TopLeft), panel.getDocumentPoint(go.Spot.RightCenter));
  // bounds.bottom = 540
  if (!allBounds) {
    allBounds = bounds;
  } else {
    allBounds = allBounds.unionRect(bounds);
  // allBounds.bottom = 539.9999999999999
  // In some other place: allBounds.containsPoint(bounds) => false

The most bottom GraphObject has a bottom coordinate of 540.
However, the resulting union Rect has a bottom coordinate of 539.9999999999999.

This is not good as I am later using go.Rect.containsPoint() Method which returns false.

Any advice?

Assume all floating point calculations are imprecise? I’m not sure what to say. I know that some of the bugs that we have had over the years are due to such programming errors on our part.

Do you think this is a bug which can be fixed or should I implement my own functionality to circumvent this behaviour?
I guess the unionRect is doing more complicated stuff, but a
allBound.bottom = max(bounds.bottom, allBounds.bottom)
shouldn’t cause floating point calculations/imprecision?

That depends on the values that the other Rects had.

For example:

539.9999999999999 < 540 === true
539.9999999999999 + 0.00000000000005 === 539.9999999999999
539.99999999999995 < 540 === false

Thanks for the explanation, I understand the issue now.
I will probably round the values before checking if the point is included in the rectangle.