From c73e777ed2755e226a4b16b71ff25e27fbb26c81 Mon Sep 17 00:00:00 2001 From: Rustam Sayfutdinov Date: Wed, 10 Jun 2020 18:53:27 +0300 Subject: [PATCH] Return hack with double.Epsilon --- src/Avalonia.Base/Properties/AssemblyInfo.cs | 1 - src/Avalonia.Base/Utilities/MathUtilities.cs | 2 +- src/Avalonia.Controls/Slider.cs | 3 +- .../Utilities/MathUtilitiesTests.cs | 29 +++++++++++++++++++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/Avalonia.Base/Properties/AssemblyInfo.cs b/src/Avalonia.Base/Properties/AssemblyInfo.cs index fd5e411850..0664f22dcb 100644 --- a/src/Avalonia.Base/Properties/AssemblyInfo.cs +++ b/src/Avalonia.Base/Properties/AssemblyInfo.cs @@ -8,4 +8,3 @@ using Avalonia.Metadata; [assembly: InternalsVisibleTo("Avalonia.Base.UnitTests")] [assembly: InternalsVisibleTo("Avalonia.UnitTests")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] -[assembly: InternalsVisibleTo("Avalonia.Controls")] diff --git a/src/Avalonia.Base/Utilities/MathUtilities.cs b/src/Avalonia.Base/Utilities/MathUtilities.cs index 6da695407b..3fb5f7a162 100644 --- a/src/Avalonia.Base/Utilities/MathUtilities.cs +++ b/src/Avalonia.Base/Utilities/MathUtilities.cs @@ -9,7 +9,7 @@ namespace Avalonia.Utilities public static class MathUtilities { // smallest such that 1.0+DoubleEpsilon != 1.0 - internal static readonly double DoubleEpsilon = 2.2204460492503131e-016; + private const double DoubleEpsilon = 2.2204460492503131e-016; /// /// AreClose - Returns whether or not two doubles are "close". That is, whether or diff --git a/src/Avalonia.Controls/Slider.cs b/src/Avalonia.Controls/Slider.cs index 6cebe32322..64378a4eb2 100644 --- a/src/Avalonia.Controls/Slider.cs +++ b/src/Avalonia.Controls/Slider.cs @@ -193,7 +193,8 @@ namespace Avalonia.Controls var orient = Orientation == Orientation.Horizontal; var pointDen = orient ? _track.Bounds.Width : _track.Bounds.Height; - pointDen += MathUtilities.DoubleEpsilon; // Just add epsilon to avoid divide by zero exceptions. + // Just add epsilon to avoid NaN in case 0/0 + pointDen += double.Epsilon; var pointNum = orient ? x.Position.X : x.Position.Y; var logicalPos = MathUtilities.Clamp(pointNum / pointDen, 0.0d, 1.0d); diff --git a/tests/Avalonia.Base.UnitTests/Utilities/MathUtilitiesTests.cs b/tests/Avalonia.Base.UnitTests/Utilities/MathUtilitiesTests.cs index 708e703a1d..a36b22fee2 100644 --- a/tests/Avalonia.Base.UnitTests/Utilities/MathUtilitiesTests.cs +++ b/tests/Avalonia.Base.UnitTests/Utilities/MathUtilitiesTests.cs @@ -1,3 +1,4 @@ +using System; using Avalonia.Utilities; using Xunit; @@ -18,6 +19,7 @@ namespace Avalonia.Base.UnitTests.Utilities var actual = MathUtilities.AreClose(x, y); Assert.True(actual); + Assert.Equal(x, Math.Round(y, 14)); } [Fact] @@ -32,6 +34,7 @@ namespace Avalonia.Base.UnitTests.Utilities var actual = MathUtilities.IsOne(x); Assert.True(actual); + Assert.Equal(1.0, Math.Round(x, 15)); } [Fact] @@ -46,6 +49,32 @@ namespace Avalonia.Base.UnitTests.Utilities var actual = MathUtilities.IsZero(x); Assert.True(actual); + Assert.Equal(0.0, Math.Round(x, 15)); + } + + [Fact] + public void Clamp_Input_NaN_Return_NaN() + { + var clamp = MathUtilities.Clamp(double.NaN, 0.0, 1.0); + Assert.True(double.IsNaN(clamp)); + } + + [Fact] + public void Clamp_Input_NegativeInfinity_Return_Min() + { + const double min = 0.0; + const double max = 1.0; + var actual = MathUtilities.Clamp(double.NegativeInfinity, min, max); + Assert.Equal(min, actual); + } + + [Fact] + public void Clamp_Input_PositiveInfinity_Return_Max() + { + const double min = 0.0; + const double max = 1.0; + var actual = MathUtilities.Clamp(double.PositiveInfinity, min, max); + Assert.Equal(max, actual); } } }