diff --git a/src/libraries/System.Private.CoreLib/src/System/Math.cs b/src/libraries/System.Private.CoreLib/src/System/Math.cs index 8432f458aec07..9e90ad9ca1176 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Math.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Math.cs @@ -539,6 +539,7 @@ public static decimal Max(decimal val1, decimal val2) return decimal.Max(val1, val2); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Max(double val1, double val2) { // This matches the IEEE 754:2019 `maximum` function @@ -547,17 +548,17 @@ public static double Max(double val1, double val2) // otherwise returns the larger of the inputs. It // treats +0 as larger than -0 as per the specification. - if ((val1 > val2) || double.IsNaN(val1)) + if (val1 != val2) { - return val1; - } + if (!double.IsNaN(val1)) + { + return val2 < val1 ? val1 : val2; + } - if (val1 == val2) - { - return double.IsNegative(val1) ? val2 : val1; + return val1; } - return val2; + return double.IsNegative(val2) ? val1 : val2; } [NonVersionable] @@ -585,6 +586,7 @@ public static sbyte Max(sbyte val1, sbyte val2) return (val1 >= val2) ? val1 : val2; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Max(float val1, float val2) { // This matches the IEEE 754:2019 `maximum` function @@ -593,17 +595,17 @@ public static float Max(float val1, float val2) // otherwise returns the larger of the inputs. It // treats +0 as larger than -0 as per the specification. - if ((val1 > val2) || float.IsNaN(val1)) + if (val1 != val2) { - return val1; - } + if (!float.IsNaN(val1)) + { + return val2 < val1 ? val1 : val2; + } - if (val1 == val2) - { - return float.IsNegative(val1) ? val2 : val1; + return val1; } - return val2; + return float.IsNegative(val2) ? val1 : val2; } [CLSCompliant(false)] @@ -663,6 +665,7 @@ public static decimal Min(decimal val1, decimal val2) return decimal.Min(val1, val2); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Min(double val1, double val2) { // This matches the IEEE 754:2019 `minimum` function @@ -671,17 +674,12 @@ public static double Min(double val1, double val2) // otherwise returns the larger of the inputs. It // treats +0 as larger than -0 as per the specification. - if ((val1 < val2) || double.IsNaN(val1)) - { - return val1; - } - - if (val1 == val2) + if (val1 != val2 && !double.IsNaN(val1)) { - return double.IsNegative(val1) ? val1 : val2; + return val1 < val2 ? val1 : val2; } - return val2; + return double.IsNegative(val1) ? val1 : val2; } [NonVersionable] @@ -709,6 +707,7 @@ public static sbyte Min(sbyte val1, sbyte val2) return (val1 <= val2) ? val1 : val2; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public static float Min(float val1, float val2) { // This matches the IEEE 754:2019 `minimum` function @@ -717,17 +716,12 @@ public static float Min(float val1, float val2) // otherwise returns the larger of the inputs. It // treats +0 as larger than -0 as per the specification. - if ((val1 < val2) || float.IsNaN(val1)) - { - return val1; - } - - if (val1 == val2) + if (val1 != val2 && !float.IsNaN(val1)) { - return float.IsNegative(val1) ? val1 : val2; + return val1 < val2 ? val1 : val2; } - return val2; + return float.IsNegative(val1) ? val1 : val2; } [CLSCompliant(false)] diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Math.cs b/src/libraries/System.Runtime.Extensions/tests/System/Math.cs index 03a9ba8b26c11..7614d2b31555e 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/Math.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/Math.cs @@ -1052,12 +1052,22 @@ public static void Max_Decimal() [Theory] [InlineData(double.NegativeInfinity, double.PositiveInfinity, double.PositiveInfinity)] - [InlineData(double.MinValue, double.MaxValue, double.MaxValue)] - [InlineData(double.NaN, double.NaN, double.NaN)] - [InlineData(-0.0, 0.0, 0.0)] - [InlineData(2.0, -3.0, 2.0)] - [InlineData(3.0, -2.0, 3.0)] - [InlineData(double.PositiveInfinity, double.NaN, double.NaN)] + [InlineData(double.PositiveInfinity, double.NegativeInfinity, double.PositiveInfinity)] + [InlineData(double.MinValue, double.MaxValue, double.MaxValue)] + [InlineData(double.MaxValue, double.MinValue, double.MaxValue)] + [InlineData(double.NaN, double.NaN, double.NaN)] + [InlineData(double.NaN, 1.0, double.NaN)] + [InlineData(1.0, double.NaN, double.NaN)] + [InlineData(double.PositiveInfinity, double.NaN, double.NaN)] + [InlineData(double.NegativeInfinity, double.NaN, double.NaN)] + [InlineData(double.NaN, double.PositiveInfinity, double.NaN)] + [InlineData(double.NaN, double.NegativeInfinity, double.NaN)] + [InlineData(-0.0, 0.0, 0.0)] + [InlineData( 0.0, -0.0, 0.0)] + [InlineData( 2.0, -3.0, 2.0)] + [InlineData(-3.0, 2.0, 2.0)] + [InlineData( 3.0, -2.0, 3.0)] + [InlineData(-2.0, 3.0, 3.0)] public static void Max_Double_NotNetFramework(double x, double y, double expectedResult) { AssertEqual(expectedResult, Math.Max(x, y), 0.0); @@ -1093,12 +1103,22 @@ public static void Max_SByte() [Theory] [InlineData(float.NegativeInfinity, float.PositiveInfinity, float.PositiveInfinity)] - [InlineData(float.MinValue, float.MaxValue, float.MaxValue)] - [InlineData(float.NaN, float.NaN, float.NaN)] - [InlineData(-0.0f, 0.0f, 0.0f)] - [InlineData(2.0f, -3.0f, 2.0f)] - [InlineData(3.0f, -2.0f, 3.0f)] - [InlineData(float.PositiveInfinity, float.NaN, float.NaN)] + [InlineData(float.PositiveInfinity, float.NegativeInfinity, float.PositiveInfinity)] + [InlineData(float.MinValue, float.MaxValue, float.MaxValue)] + [InlineData(float.MaxValue, float.MinValue, float.MaxValue)] + [InlineData(float.NaN, float.NaN, float.NaN)] + [InlineData(float.NaN, 1.0, float.NaN)] + [InlineData(1.0, float.NaN, float.NaN)] + [InlineData(float.PositiveInfinity, float.NaN, float.NaN)] + [InlineData(float.NegativeInfinity, float.NaN, float.NaN)] + [InlineData(float.NaN, float.PositiveInfinity, float.NaN)] + [InlineData(float.NaN, float.NegativeInfinity, float.NaN)] + [InlineData(-0.0, 0.0, 0.0)] + [InlineData( 0.0, -0.0, 0.0)] + [InlineData( 2.0, -3.0, 2.0)] + [InlineData(-3.0, 2.0, 2.0)] + [InlineData( 3.0, -2.0, 3.0)] + [InlineData(-2.0, 3.0, 3.0)] public static void Max_Single_NotNetFramework(float x, float y, float expectedResult) { AssertEqual(expectedResult, Math.Max(x, y), 0.0f); @@ -1141,12 +1161,22 @@ public static void Min_Decimal() [Theory] [InlineData(double.NegativeInfinity, double.PositiveInfinity, double.NegativeInfinity)] - [InlineData(double.MinValue, double.MaxValue, double.MinValue)] - [InlineData(double.NaN, double.NaN, double.NaN)] - [InlineData(-0.0, 0.0, -0.0)] - [InlineData(2.0, -3.0, -3.0)] - [InlineData(3.0, -2.0, -2.0)] - [InlineData(double.PositiveInfinity, double.NaN, double.NaN)] + [InlineData(double.PositiveInfinity, double.NegativeInfinity, double.NegativeInfinity)] + [InlineData(double.MinValue, double.MaxValue, double.MinValue)] + [InlineData(double.MaxValue, double.MinValue, double.MinValue)] + [InlineData(double.NaN, double.NaN, double.NaN)] + [InlineData(double.NaN, 1.0, double.NaN)] + [InlineData(1.0, double.NaN, double.NaN)] + [InlineData(double.PositiveInfinity, double.NaN, double.NaN)] + [InlineData(double.NegativeInfinity, double.NaN, double.NaN)] + [InlineData(double.NaN, double.PositiveInfinity, double.NaN)] + [InlineData(double.NaN, double.NegativeInfinity, double.NaN)] + [InlineData(-0.0, 0.0, -0.0)] + [InlineData( 0.0, -0.0, -0.0)] + [InlineData( 2.0, -3.0, -3.0)] + [InlineData(-3.0, 2.0, -3.0)] + [InlineData( 3.0, -2.0, -2.0)] + [InlineData(-2.0, 3.0, -2.0)] public static void Min_Double_NotNetFramework(double x, double y, double expectedResult) { AssertEqual(expectedResult, Math.Min(x, y), 0.0); @@ -1182,12 +1212,22 @@ public static void Min_SByte() [Theory] [InlineData(float.NegativeInfinity, float.PositiveInfinity, float.NegativeInfinity)] - [InlineData(float.MinValue, float.MaxValue, float.MinValue)] - [InlineData(float.NaN, float.NaN, float.NaN)] - [InlineData(-0.0f, 0.0f, -0.0f)] - [InlineData(2.0f, -3.0f, -3.0f)] - [InlineData(3.0f, -2.0f, -2.0f)] - [InlineData(float.PositiveInfinity, float.NaN, float.NaN)] + [InlineData(float.PositiveInfinity, float.NegativeInfinity, float.NegativeInfinity)] + [InlineData(float.MinValue, float.MaxValue, float.MinValue)] + [InlineData(float.MaxValue, float.MinValue, float.MinValue)] + [InlineData(float.NaN, float.NaN, float.NaN)] + [InlineData(float.NaN, 1.0, float.NaN)] + [InlineData(1.0, float.NaN, float.NaN)] + [InlineData(float.PositiveInfinity, float.NaN, float.NaN)] + [InlineData(float.NegativeInfinity, float.NaN, float.NaN)] + [InlineData(float.NaN, float.PositiveInfinity, float.NaN)] + [InlineData(float.NaN, float.NegativeInfinity, float.NaN)] + [InlineData(-0.0, 0.0, -0.0)] + [InlineData( 0.0, -0.0, -0.0)] + [InlineData( 2.0, -3.0, -3.0)] + [InlineData(-3.0, 2.0, -3.0)] + [InlineData( 3.0, -2.0, -2.0)] + [InlineData(-2.0, 3.0, -2.0)] public static void Min_Single_NotNetFramework(float x, float y, float expectedResult) { AssertEqual(expectedResult, Math.Min(x, y), 0.0f);