Browse Source

Handle FP errors in RoundLayoutValueUp.

If the `value` passed to `RoundLayoutValueUp` has a floating point precision error (e.g. 79.333333333333343 in the test case) then when it's multiplied by `dpiScale` and rounded up, it will be rounded up to the a value one greater than it should be.

Fix this by rounding the initial value to an arbitrary precision of 8 digits.

Fixes #8866
pull/8882/head
Steven Kirk 4 years ago
parent
commit
76747d32b4
  1. 11
      src/Avalonia.Base/Layout/LayoutHelper.cs

11
src/Avalonia.Base/Layout/LayoutHelper.cs

@ -251,6 +251,17 @@ namespace Avalonia.Layout
{
double newValue;
// Round the value to avoid FP errors. This is needed because if `value` has a floating
// point precision error (e.g. 79.333333333333343) then when it's multiplied by
// `dpiScale` and rounded up, it will be rounded up to a value one greater than it
// should be.
#if NET6_0_OR_GREATER
value = Math.Round(value, 8, MidpointRounding.ToZero);
#else
// MidpointRounding.ToZero isn't available in netstandard2.0.
value = Math.Truncate(value * 1e8) / 1e8;
#endif
// If DPI == 1, don't use DPI-aware rounding.
if (!MathUtilities.IsOne(dpiScale))
{

Loading…
Cancel
Save