Skip to content

Don't break a flex line on floating-point rounding noise - #59186

Open
javache wants to merge 1 commit into
react:mainfrom
javache:export-D126040642
Open

javache wants to merge 1 commit into
react:mainfrom
javache:export-D126040642

Conversation

@javache

@javache javache commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

Summary:
A content-sized wrapping row sizes itself to the max-content sum of its items, then recovers the space available to those items by subtracting its padding and border back off (calculateAvailableInnerDimension). In float32 that add-then-subtract round-trip can land a fraction of an ulp below the sum it came from.

For an item with a measure function the measurement cache still returns the max-content measurement in that situation: oldSizeIsMaxContentAndStillFits accepts a cached width up to the inexactEquals epsilon (1e-4) wider than the space now available. calculateFlexLine then compared that basis against availableInnerMainDim with a bare >, so the basis the cache had just accepted as fitting read as overflow and the line broke.

Because the container had already been sized for a single line, the result was a box one line tall with its items laid out on two, overflowing its own padding and border. In React Native this reproduced on both iOS and Android and was extremely sensitive to the measured text width, since only some values leave a residue inside the window.

Make the overflow test tolerant of the same epsilon the cache uses, so the two agree. Items without a measure function are unaffected: they take their exact style width in both passes and never enter that cache path.

The regression test sweeps fractional measured widths whose content sum sits just under 128 while the outer width sits just over it, so adding padding and border crosses a float32 binade and the subtraction cannot always recover the original value.

Changelog: [Internal]

X-link: react/yoga#2022

Differential Revision: D126040642

Pulled By: javache

Summary:
A content-sized wrapping row sizes itself to the max-content sum of its items, then recovers the space available to those items by subtracting its padding and border back off (calculateAvailableInnerDimension). In float32 that add-then-subtract round-trip can land a fraction of an ulp below the sum it came from.

For an item with a measure function the measurement cache still returns the max-content measurement in that situation: oldSizeIsMaxContentAndStillFits accepts a cached width up to the inexactEquals epsilon (1e-4) wider than the space now available. calculateFlexLine then compared that basis against availableInnerMainDim with a bare `>`, so the basis the cache had just accepted as fitting read as overflow and the line broke.

Because the container had already been sized for a single line, the result was a box one line tall with its items laid out on two, overflowing its own padding and border. In React Native this reproduced on both iOS and Android and was extremely sensitive to the measured text width, since only some values leave a residue inside the window.

Make the overflow test tolerant of the same epsilon the cache uses, so the two agree. Items without a measure function are unaffected: they take their exact style width in both passes and never enter that cache path.

The regression test sweeps fractional measured widths whose content sum sits just under 128 while the outer width sits just over it, so adding padding and border crosses a float32 binade and the subtraction cannot always recover the original value.

Changelog: [Internal]

X-link: react/yoga#2022

Differential Revision: D126040642

Pulled By: javache
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 19, 2026
@meta-codesync

meta-codesync Bot commented Oct 19, 2026

Copy link
Copy Markdown

@javache has exported this pull request. If you are a Meta employee, you can view the originating Diff in D126040642.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants