From a9c56caf843eaee52cdded8f8e547434def8de9b Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Tue, 23 Nov 2021 23:17:05 +0100 Subject: [PATCH] Optimize `Math.NearEqual` --- Source/Engine/Core/Math/Math.h | 47 ++++++++++---------------------- Source/Engine/Core/Math/Mathf.cs | 26 +++++------------- 2 files changed, 22 insertions(+), 51 deletions(-) diff --git a/Source/Engine/Core/Math/Math.h b/Source/Engine/Core/Math/Math.h index df280cce9..b5320dd35 100644 --- a/Source/Engine/Core/Math/Math.h +++ b/Source/Engine/Core/Math/Math.h @@ -419,7 +419,7 @@ namespace Math return (T)0; return Saturate((value - a) / (b - a)); } - + // Performs smooth (cubic Hermite) interpolation between 0 and 1 // @param amount Value between 0 and 1 indicating interpolation amount static float SmoothStep(float amount) @@ -480,44 +480,16 @@ namespace Math } /// - /// Checks if a and b are not even almost equal, taking into account the magnitude of floating point numbers - /// - /// The left value to compare - /// The right value to compare - /// False if a almost equal to b, otherwise true - static bool NotNearEqual(float a, float b) - { - // Check if the numbers are really close - needed when comparing numbers near zero - if (IsZero(a - b)) - return false; - - // Original from Bruce Dawson: http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ - const int32 aInt = *(int32*)&a; - const int32 bInt = *(int32*)&b; - - // Different signs means they do not match - if (aInt < 0 != bInt < 0) - return true; - - // Find the difference in ULPs - const int ulp = Abs(aInt - bInt); - - // Choose of maxUlp = 4 - // according to http://code.google.com/p/googletest/source/browse/trunk/include/gtest/internal/gtest-internal.h - const int maxUlp = 4; - return ulp > maxUlp; - } - - /// - /// Checks if a and b are almost equals, taking into account the magnitude of floating point numbers + /// Checks if a and b are almost equals, taking into account the magnitude of floating point numbers. /// + /// The code is using the technique described by Bruce Dawson in Comparing Floating point numbers 2012 edition. /// The left value to compare /// The right value to compare /// True if a almost equal to b, otherwise false static bool NearEqual(float a, float b) { // Check if the numbers are really close - needed when comparing numbers near zero - if (IsZero(a - b)) + if (Abs(a) < ZeroTolerance) return true; // Original from Bruce Dawson: http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ @@ -537,6 +509,17 @@ namespace Math return ulp <= maxUlp; } + /// + /// Checks if a and b are not even almost equal, taking into account the magnitude of floating point numbers + /// + /// The left value to compare + /// The right value to compare + /// False if a almost equal to b, otherwise true + static FORCE_INLINE bool NotNearEqual(float a, float b) + { + return !NearEqual(a, b); + } + /// /// Checks if a and b are almost equals within the given epsilon value. /// diff --git a/Source/Engine/Core/Math/Mathf.cs b/Source/Engine/Core/Math/Mathf.cs index 21a800a51..52424fa33 100644 --- a/Source/Engine/Core/Math/Mathf.cs +++ b/Source/Engine/Core/Math/Mathf.cs @@ -586,8 +586,7 @@ namespace FlaxEngine /// The maximum speed. /// The delta time (in seconds) since last update. /// The smoothed value. - public static float SmoothDamp(float current, float target, ref float currentVelocity, float smoothTime, [DefaultValue("float.PositiveInfinity")] - float maxSpeed, [DefaultValue("Time.DeltaTime")] float deltaTime) + public static float SmoothDamp(float current, float target, ref float currentVelocity, float smoothTime, [DefaultValue("float.PositiveInfinity")] float maxSpeed, [DefaultValue("Time.DeltaTime")] float deltaTime) { smoothTime = Max(0.0001f, smoothTime); float a = 2f / smoothTime; @@ -646,8 +645,7 @@ namespace FlaxEngine /// The maximum speed. /// The delta time (in seconds) since last update. /// The smoothed value. - public static float SmoothDampAngle(float current, float target, ref float currentVelocity, float smoothTime, [DefaultValue("float.PositiveInfinity")] - float maxSpeed, [DefaultValue("Time.DeltaTime")] float deltaTime) + public static float SmoothDampAngle(float current, float target, ref float currentVelocity, float smoothTime, [DefaultValue("float.PositiveInfinity")] float maxSpeed, [DefaultValue("Time.DeltaTime")] float deltaTime) { target = current + DeltaAngle(current, target); return SmoothDamp(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime); @@ -905,26 +903,16 @@ namespace FlaxEngine } /// - /// Checks if a and b are almost equals, taking into account the magnitude of floating point numbers (unlike - /// method). See Remarks. - /// See remarks. + /// Checks if a and b are almost equals, taking into account the magnitude of floating point numbers (unlike method). /// /// The left value to compare. /// The right value to compare. /// true if a almost equal to b, false otherwise - /// - /// The code is using the technique described by Bruce Dawson in - /// - /// Comparing - /// Floating point numbers 2012 edition - /// - /// . - /// + /// The code is using the technique described by Bruce Dawson in Comparing Floating point numbers 2012 edition. public static unsafe bool NearEqual(float a, float b) { - // Check if the numbers are really close -- needed - // when comparing numbers near zero. - if (IsZero(a - b)) + // Check if the numbers are really close -- needed when comparing numbers near zero. + if (Math.Abs(a - b) < Epsilon) return true; // Original from Bruce Dawson: http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ @@ -973,7 +961,7 @@ namespace FlaxEngine /// true if the specified value is close to one (1.0f); otherwise, false. public static bool IsOne(float a) { - return IsZero(a - 1.0f); + return Math.Abs(a - 1.0f) < Epsilon; } ///