This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
lerpDouble: stricter handling of NaN and infinity #20871
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Hixie
reviewed
Aug 29, 2020
lib/ui/lerp.dart
Outdated
| /// Linearly interpolate between two numbers, `a` and `b`, by an extrapolation | ||
| /// factor `t`. | ||
| /// | ||
| /// When both `a` and `b` are null, infinite, or NaN, `a` is returned. |
Contributor
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line is confusing. I thought for a minute that it meant that lerpDouble(null, double.infinity, 1.0) would return null.
Member
Author
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hrm -- indeed. Re-worded a little. Let me know if that still parses badly.
Hixie
reviewed
Aug 29, 2020
Hixie
reviewed
Aug 29, 2020
Hixie
approved these changes
Aug 29, 2020
Contributor
Hixie
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Member
Author
|
This is currently rebased on #20874. |
This was referenced Aug 29, 2020
This extracts a Dart test utilities library, containing `expectAssertion` and `expectArgumentError` functions that simplify running tests that test assertions across debug, profile, and release configurations. This change also restricts Dart unit tests to testing files whose filename matches `*_test.dart` under `flutter/testing/dart`; previously any file in that directory was run, but all files matched the above pattern.
Previously, the behaviour of lerpDouble with respect to NaN and infinity was relatively complex and difficult to reason about. This patch simplifies the behaviour with respect to those conditions and adds documentation and tests. In general, if `a == b` or both values are null, infinite, or NaN, `a` is returned. Otherwise we require `a` and `b` and `t` to be finite or null and the result of the linear interpolation is returned.
engine-flutter-autoroll
added a commit
to engine-flutter-autoroll/flutter
that referenced
this pull request
Aug 30, 2020
cbracken
added a commit
that referenced
this pull request
Sep 8, 2020
This updates the web_ui implementation of lerpDouble to match the behaviour of the C++ engine implementation in dart:ui. Specifically this covers the following changes: * #20871: stricter handling of NaN and infinity * #20879: Improve the precision of lerpDouble lerpDouble: stricter handling of NaN and infinity (#20871) ---------------------------------------------------------- Previously, the behaviour of lerpDouble with respect to NaN and infinity was relatively complex and difficult to reason about. This patch simplifies the behaviour with respect to those conditions and adds documentation and tests. In general, if `a == b` or both values are null, infinite, or NaN, `a` is returned. Otherwise we require `a` and `b` and `t` to be finite or null and the result of the linear interpolation is returned. Improve the precision of lerpDouble (#20879) -------------------------------------------- Reduces errors caused by the loss of floating point precision when the two extrema of the lerp differ significantly in magnitude. Previously, we used the calculation: a + (b - a) * t When the difference in magnitude between `a` and `b` exceeds the precision representable by double-precision floating point math, `b - a` results in the larger-magnitude value of `a` or `b`. The error between the value produced and the correct value is then scaled by t. A simple example of the impact can be seen when `a` is significantly larger in magnitude than `b`. In that case, `b - a` results in `a` and when `t` is 1.0, the resulting value is `a - (a) * 1.0 == 0`. The patch transforms the computation to the mathematically-equivalent expression: a * (1.0 - t) + b * t By scaling each value independently, the behaviour is more accurate. From the point of view of performance, this adds an extra multiplication, but multiplication is relatively cheap and the behaviour is significantly better. This patch also adds a `precisionErrorTolerance` constant to test_utils.dart and migrates existing tests to use `closeTo()` for testing. The tests themselves *do* currently use values that have an exact floating-point representation, but we should allow for flexibility in future implementation changes.
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Previously, the behaviour of lerpDouble with respect to NaN and infinity was relatively complex and difficult to reason about. This patch simplifies the behaviour with respect to those conditions and adds documentation and tests.
In general, if
a == bor both values are null, infinite, or NaN,ais returned. Otherwise we requireaandbandtto be finite or null and the result of the linear interpolation is returned.See related patches #20848 and #20778.