On Fri, 28 Feb 2025 21:46:13 GMT, Andy Goryachev <ango...@openjdk.org> wrote:
>> That's absolutely true, however this can change quickly when large values >> are added or subtracted to/from small values, or when division or >> multiplication gets involved. So I'd say its relatively safe to do simple >> calculations with near snapped values, but one must be careful with >> functions like `ceil` and `floor` as they can amplify tiny floating-point >> errors due to their discontinuous nature. For example, if take a snapped >> `spacing` and add a snapped `left` and `right` margin, then call ceil on the >> result, it could go like this: >> >> 1.99999999999999 + >> 4.00000000000001 + >> 4.00000000000001 = >> 10.00000000000001 -> ceil -> 11 (instead of the expected 10) > > good point! > > This is exactly the reason for the code in ScaledMath:71 > > return Math.ceil(d - Math.ulp(d)) / scale; Come to think of it, most the issues here are caused by using functions like `floor` and `ceil`. It might be an idea to change these functions to bias them slightly towards rounding to the closest value, instead of always doing a straight up `floor` or `ceil`. For example, let's say I calculate a size as `3.0000001`; ceiling this (with snapSize) to `4` is quite ridiculous; obviously `3` was intended, but the ceiling function won't care. But what if we subtracted a value (assuming we're dealing with pixels of course, which the `snap` functions are)? We could bias it slightly towards the correct value by using something ridiculously small like 1/10000th of a pixel. For example: `3.0000001` - 1/10000th of a pixel = `2.9999`. Ceiling this value yields the intended `3`. We could work much safer with near snapped values, as there is much less risk of a one ulp difference being dramatically amplified by floor/ceil functions. ------------- PR Review Comment: https://git.openjdk.org/jfx/pull/1723#discussion_r1976045508