Skip to content

Discrete range slider has no floating-point rounding errors - #187393

Closed
hannah-hyj wants to merge 1 commit into
flutter:masterfrom
hannah-hyj:slider-double
Closed

hannah-hyj wants to merge 1 commit into
flutter:masterfrom
hannah-hyj:slider-double

Conversation

@hannah-hyj

Copy link
Copy Markdown
Member

fix: #39510

Before:
value1 =29.0/35.0;
value2 =value1* 35.0;

we will get value1 = 29.000000000000004

After: value = 29.0 *35.0/ 35.0

we will get value =29.0; no more floating-point rounding errors;

Pre-launch Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

If this change needs to override an active code freeze, provide a comment explaining why. The code freeze workflow can be overridden by code reviewers. See pinned issues for any active code freezes with guidance.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jun 1, 2026
@github-actions github-actions Bot added framework flutter/packages/flutter repository. See also f: labels. p: material_ui material_ui package in flutter/packages labels Jun 1, 2026
@hannah-hyj hannah-hyj added the waiting for code freeze This PR is waiting for a code freeze to resolve. label Jun 1, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the _lerp calculations in RangeSlider and Slider to handle discrete divisions when widget.divisions is specified, preventing floating-point rounding errors. Corresponding widget tests are added to verify this behavior. The reviewer suggests refactoring both _lerp methods to assign widget.divisions to a local variable, which leverages Dart's type promotion and avoids repeated null-assertion operators.

Comment on lines +584 to +590
double _lerp(double value) {
if (widget.divisions != null) {
return widget.min +
(value * widget.divisions!).round() * (widget.max - widget.min) / widget.divisions!;
}
return ui.lerpDouble(widget.min, widget.max, value)!;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Instead of repeatedly using the null-assertion operator ! on widget.divisions, we can assign it to a local variable. Dart's type promotion will then automatically promote it to a non-nullable int inside the if block, making the code cleaner and safer.

  double _lerp(double value) {
    final int? divisions = widget.divisions;
    if (divisions != null) {
      return widget.min +
          (value * divisions).round() * (widget.max - widget.min) / divisions;
    }
    return ui.lerpDouble(widget.min, widget.max, value)!;
  }

Comment on lines 776 to 784
double _lerp(double value) {
assert(value >= 0.0);
assert(value <= 1.0);
if (widget.divisions != null) {
return widget.min +
(value * widget.divisions!).round() * (widget.max - widget.min) / widget.divisions!;
}
return value * (widget.max - widget.min) + widget.min;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Instead of repeatedly using the null-assertion operator ! on widget.divisions, we can assign it to a local variable. Dart's type promotion will then automatically promote it to a non-nullable int inside the if block, making the code cleaner and safer.

  double _lerp(double value) {
    assert(value >= 0.0);
    assert(value <= 1.0);
    final int? divisions = widget.divisions;
    if (divisions != null) {
      return widget.min +
          (value * divisions).round() * (widget.max - widget.min) / divisions;
    }
    return value * (widget.max - widget.min) + widget.min;
  }

@hannah-hyj
hannah-hyj marked this pull request as draft June 1, 2026 18:38
@flutter-dashboard

Copy link
Copy Markdown

This pull request has been changed to a draft. The currently pending flutter-gold status will not be able to resolve until a new commit is pushed or the change is marked ready for review again.

For more guidance, visit Writing a golden file test for package:flutter.

Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing.

@Piinks Piinks added the Decoupling: Not ready to port yet Instructions will be provided when this is ready to move to flutter/packages. label Jun 24, 2026
@Piinks

Piinks commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

I've marked this PR as not ready to port to flutter/packages yet.
We'll provide instructions to move this change over to material_ui/cupertino_ui once ready to receive PRs. Thank you!

@Piinks Piinks added Decoupling: Port to flutter/packages This PR is ready to be ported to flutter/packages. We will provide instructions to do so. and removed waiting for code freeze This PR is waiting for a code freeze to resolve. Decoupling: Not ready to port yet Instructions will be provided when this is ready to move to flutter/packages. labels Sep 9, 2026
@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

This pull request contains changes to Material or Cupertino, which are currently frozen in this repository.

Changes should be made in material_ui and/or cupertino_ui in the flutter/packages repository.

Please refer to #188444 for instructions.

@Piinks

Piinks commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

This PR is now ready to port over to flutter/packages! 🥳
See guidance and instructions in #188444

hannah-hyj added a commit to hannah-hyj/packages that referenced this pull request Sep 25, 2026
…and RangeSlider

Fixes floating-point rounding errors when calculating values for discrete `Slider` and `RangeSlider`.

Ports flutter/flutter#187393 to `material_ui`.
Fixes flutter/flutter#39510
@hannah-hyj hannah-hyj closed this Sep 25, 2026
hannah-hyj added a commit to hannah-hyj/packages that referenced this pull request Sep 28, 2026
…and RangeSlider

Fixes floating-point rounding errors when calculating values for discrete `Slider` and `RangeSlider`.

Ports flutter/flutter#187393 to `material_ui`.
Fixes flutter/flutter#39510
auto-submit Bot pushed a commit to flutter/packages that referenced this pull request Sep 28, 2026
…and RangeSlider (#13022)

Fixes floating-point rounding errors when calculating values for discrete `Slider` and `RangeSlider`.

Ports flutter/flutter#187393 to `material_ui`.
Fixes flutter/flutter#39510

## Pre-Review Checklist

**Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

[^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CICD Run CI/CD Decoupling: Port to flutter/packages This PR is ready to be ported to flutter/packages. We will provide instructions to do so. framework flutter/packages/flutter repository. See also f: labels. p: material_ui material_ui package in flutter/packages

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Discrete Slider/RangeSlider has interpolation (?) errors

2 participants