diff --git a/src/System.Runtime.Extensions/ref/System.Runtime.Extensions.cs b/src/System.Runtime.Extensions/ref/System.Runtime.Extensions.cs index b6806bc31ce6..28ddbdef40c0 100644 --- a/src/System.Runtime.Extensions/ref/System.Runtime.Extensions.cs +++ b/src/System.Runtime.Extensions/ref/System.Runtime.Extensions.cs @@ -780,6 +780,8 @@ public static partial class Math public static double Atan2(double y, double x) { throw null; } public static double Atanh(double d) { throw null; } public static long BigMul(int a, int b) { throw null; } + public static double BitDecrement(double x) { throw null; } + public static double BitIncrement(double x) { throw null; } public static double Cbrt(double d) { throw null; } public static decimal Ceiling(decimal d) { throw null; } public static double Ceiling(double a) { throw null; } @@ -798,6 +800,7 @@ public static partial class Math public static uint Clamp(uint value, uint min, uint max) { throw null; } [System.CLSCompliantAttribute(false)] public static ulong Clamp(ulong value, ulong min, ulong max) { throw null; } + public static double CopySign(double x, double y) { throw null; } public static double Cos(double d) { throw null; } public static double Cosh(double value) { throw null; } public static int DivRem(int a, int b, out int result) { throw null; } @@ -805,9 +808,12 @@ public static partial class Math public static double Exp(double d) { throw null; } public static decimal Floor(decimal d) { throw null; } public static double Floor(double d) { throw null; } + public static double FusedMultiplyAdd(double x, double y, double z) { throw null; } public static double IEEERemainder(double x, double y) { throw null; } + public static int ILogB(double x) { throw null; } public static double Log(double d) { throw null; } public static double Log(double a, double newBase) { throw null; } + public static double Log2(double x) { throw null; } public static double Log10(double d) { throw null; } public static byte Max(byte val1, byte val2) { throw null; } public static decimal Max(decimal val1, decimal val2) { throw null; } @@ -824,6 +830,7 @@ public static partial class Math public static uint Max(uint val1, uint val2) { throw null; } [System.CLSCompliantAttribute(false)] public static ulong Max(ulong val1, ulong val2) { throw null; } + public static double MaxMagnitude(double x, double y) { throw null; } public static byte Min(byte val1, byte val2) { throw null; } public static decimal Min(decimal val1, decimal val2) { throw null; } public static double Min(double val1, double val2) { throw null; } @@ -839,6 +846,7 @@ public static partial class Math public static uint Min(uint val1, uint val2) { throw null; } [System.CLSCompliantAttribute(false)] public static ulong Min(ulong val1, ulong val2) { throw null; } + public static double MinMagnitude(double x, double y) { throw null; } public static double Pow(double x, double y) { throw null; } public static decimal Round(decimal d) { throw null; } public static decimal Round(decimal d, int decimals) { throw null; } @@ -848,6 +856,7 @@ public static partial class Math public static double Round(double value, int digits) { throw null; } public static double Round(double value, int digits, System.MidpointRounding mode) { throw null; } public static double Round(double value, System.MidpointRounding mode) { throw null; } + public static double ScaleB(double x, int n) { throw null; } public static int Sign(decimal value) { throw null; } public static int Sign(double value) { throw null; } public static int Sign(short value) { throw null; } @@ -874,23 +883,32 @@ public static partial class MathF public static float Atan(float x) { throw null; } public static float Atanh(float x) { throw null; } public static float Atan2(float y, float x) { throw null; } + public static float BitDecrement(float x) { throw null; } + public static float BitIncrement(float x) { throw null; } public static float Cbrt(float x) { throw null; } public static float Ceiling(float x) { throw null; } + public static float CopySign(float x, float y) { throw null; } public static float Cos(float x) { throw null; } public static float Cosh(float x) { throw null; } public static float Exp(float x) { throw null; } public static float Floor(float x) { throw null; } + public static float FusedMultiplyAdd(float x, float y, float z) { throw null; } public static float IEEERemainder(float x, float y) { throw null; } + public static int ILogB(float x) { throw null; } public static float Log(float x) { throw null; } public static float Log(float x, float y) { throw null; } + public static float Log2(float x) { throw null; } public static float Log10(float x) { throw null; } public static float Max(float x, float y) { throw null; } + public static float MaxMagnitude(float x, float y) { throw null; } public static float Min(float x, float y) { throw null; } + public static float MinMagnitude(float x, float y) { throw null; } public static float Pow(float x, float y) { throw null; } public static float Round(float x) { throw null; } public static float Round(float x, int digits) { throw null; } public static float Round(float x, int digits, System.MidpointRounding mode) { throw null; } public static float Round(float x, System.MidpointRounding mode) { throw null; } + public static float ScaleB(float x, int n) { throw null; } public static int Sign(float x) { throw null; } public static float Sin(float x) { throw null; } public static float Sinh(float x) { throw null; } diff --git a/src/System.Runtime.Extensions/src/ApiCompatBaseline.netcoreappaot.txt b/src/System.Runtime.Extensions/src/ApiCompatBaseline.netcoreappaot.txt new file mode 100644 index 000000000000..5ddd14a9846e --- /dev/null +++ b/src/System.Runtime.Extensions/src/ApiCompatBaseline.netcoreappaot.txt @@ -0,0 +1,10 @@ +Compat issues with assembly System.Runtime.Extensions: +MembersMustExist : Member 'System.Math.FusedMultiplyAdd(System.Double, System.Double, System.Double)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'System.Math.ILogB(System.Double)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'System.Math.Log2(System.Double)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'System.Math.ScaleB(System.Double, System.Int32)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'System.MathF.FusedMultiplyAdd(System.Single, System.Single, System.Single)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'System.MathF.ILogB(System.Single)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'System.MathF.Log2(System.Single)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'System.MathF.ScaleB(System.Single, System.Int32)' does not exist in the implementation but it does exist in the contract. +Total Issues: 8 diff --git a/src/System.Runtime.Extensions/src/ApiCompatBaseline.uapaot.txt b/src/System.Runtime.Extensions/src/ApiCompatBaseline.uapaot.txt new file mode 100644 index 000000000000..5ddd14a9846e --- /dev/null +++ b/src/System.Runtime.Extensions/src/ApiCompatBaseline.uapaot.txt @@ -0,0 +1,10 @@ +Compat issues with assembly System.Runtime.Extensions: +MembersMustExist : Member 'System.Math.FusedMultiplyAdd(System.Double, System.Double, System.Double)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'System.Math.ILogB(System.Double)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'System.Math.Log2(System.Double)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'System.Math.ScaleB(System.Double, System.Int32)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'System.MathF.FusedMultiplyAdd(System.Single, System.Single, System.Single)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'System.MathF.ILogB(System.Single)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'System.MathF.Log2(System.Single)' does not exist in the implementation but it does exist in the contract. +MembersMustExist : Member 'System.MathF.ScaleB(System.Single, System.Int32)' does not exist in the implementation but it does exist in the contract. +Total Issues: 8 diff --git a/src/System.Runtime.Extensions/tests/System/Math.cs b/src/System.Runtime.Extensions/tests/System/Math.cs index 4c17687661bd..8e9d36e665df 100644 --- a/src/System.Runtime.Extensions/tests/System/Math.cs +++ b/src/System.Runtime.Extensions/tests/System/Math.cs @@ -1077,6 +1077,8 @@ public static void Max_Double_NetFramework() [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.PositiveInfinity)] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] @@ -1128,6 +1130,8 @@ public static void Max_Single_NetFramework() [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.PositiveInfinity)] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] @@ -1186,6 +1190,8 @@ public static void Min_Double_NetFramework() [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.PositiveInfinity)] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] @@ -1237,7 +1243,9 @@ public static void Min_Single_NetFramework() [InlineData(float.NegativeInfinity, float.PositiveInfinity, float.NegativeInfinity)] [InlineData(float.MinValue, float.MaxValue, float.MinValue)] [InlineData(float.NaN, float.NaN, float.NaN)] - [InlineData(3.0, -2.0, -2.0)] + [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.PositiveInfinity)] [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)] public static void Min_Single_NotNetFramework(float x, float y, float expectedResult) diff --git a/src/System.Runtime.Extensions/tests/System/MathF.netcoreapp.cs b/src/System.Runtime.Extensions/tests/System/MathF.netcoreapp.cs index ac71ad94fa03..a898d70dece3 100644 --- a/src/System.Runtime.Extensions/tests/System/MathF.netcoreapp.cs +++ b/src/System.Runtime.Extensions/tests/System/MathF.netcoreapp.cs @@ -128,7 +128,7 @@ private static void AssertEqual(float expected, float actual, float variance) // and we should fallback to checking if it is within the allowed variance instead. } - var delta = Math.Abs(actual - expected); + var delta = MathF.Abs(actual - expected); if (delta > variance) { @@ -150,15 +150,15 @@ private unsafe static bool IsPositiveZero(float value) // but also NaN and ±∞) are correctly and consistently represented. private static string ToStringPadded(float value) { - if (double.IsNaN(value)) + if (float.IsNaN(value)) { return "NaN".PadLeft(10); } - else if (double.IsPositiveInfinity(value)) + else if (float.IsPositiveInfinity(value)) { return "+∞".PadLeft(10); } - else if (double.IsNegativeInfinity(value)) + else if (float.IsNegativeInfinity(value)) { return "-∞".PadLeft(10); } @@ -561,6 +561,84 @@ public static void Atanh(float value, float expectedResult, float allowedVarianc AssertEqual(expectedResult, MathF.Atanh(value), allowedVariance); } + [Theory] + [InlineData( float.NegativeInfinity, float.NegativeInfinity)] + [InlineData(-3.14159265f, -3.14159298f)] // value: -(pi) + [InlineData(-2.71828183f, -2.71828198f)] // value: -(e) + [InlineData(-2.30258509f, -2.30258536f)] // value: -(ln(10)) + [InlineData(-1.57079633f, -1.57079649f)] // value: -(pi / 2) + [InlineData(-1.44269504f, -1.44269514f)] // value: -(log2(e)) + [InlineData(-1.41421356f, -1.41421366f)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, -1.12837934f)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, -1.00000012f)] + [InlineData(-0.785398163f, -0.785398245f)] // value: -(pi / 4) + [InlineData(-0.707106781f, -0.707106829f)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, -0.693147242f)] // value: -(ln(2)) + [InlineData(-0.636619772f, -0.636619806f)] // value: -(2 / pi) + [InlineData(-0.434294482f, -0.434294522f)] // value: -(log10(e)) + [InlineData(-0.318309886f, -0.318309903f)] // value: -(1 / pi) + [InlineData(-0.0f, -float.Epsilon)] + [InlineData( float.NaN, float.NaN)] + [InlineData( 0.0f, -float.Epsilon)] + [InlineData( 0.318309886f, 0.318309844f)] // value: (1 / pi) + [InlineData( 0.434294482f, 0.434294462f)] // value: (log10(e)) + [InlineData( 0.636619772f, 0.636619687f)] // value: (2 / pi) + [InlineData( 0.693147181f, 0.693147123f)] // value: (ln(2)) + [InlineData( 0.707106781f, 0.707106709f)] // value: (1 / sqrt(2)) + [InlineData( 0.785398163f, 0.785398126f)] // value: (pi / 4) + [InlineData( 1.0f, 0.999999940f)] + [InlineData( 1.12837917f, 1.12837911f)] // value: (2 / sqrt(pi)) + [InlineData( 1.41421356f, 1.41421342f)] // value: (sqrt(2)) + [InlineData( 1.44269504f, 1.44269490f)] // value: (log2(e)) + [InlineData( 1.57079633f, 1.57079625f)] // value: (pi / 2) + [InlineData( 2.30258509f, 2.30258489f)] // value: (ln(10)) + [InlineData( 2.71828183f, 2.71828151f)] // value: (e) + [InlineData( 3.14159265f, 3.14159250f)] // value: (pi) + [InlineData( float.PositiveInfinity, float.MaxValue)] + public static void BitDecrement(float value, float expectedResult) + { + AssertEqual(expectedResult, MathF.BitDecrement(value), 0.0f); + } + + [Theory] + [InlineData( float.NegativeInfinity, float.MinValue)] + [InlineData(-3.14159265f, -3.14159250f)] // value: -(pi) + [InlineData(-2.71828183f, -2.71828151f)] // value: -(e) + [InlineData(-2.30258509f, -2.30258489f)] // value: -(ln(10)) + [InlineData(-1.57079633f, -1.57079625f)] // value: -(pi / 2) + [InlineData(-1.44269504f, -1.44269490f)] // value: -(log2(e)) + [InlineData(-1.41421356f, -1.41421342f)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, -1.12837911f)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, -0.999999940f)] + [InlineData(-0.785398163f, -0.785398126f)] // value: -(pi / 4) + [InlineData(-0.707106781f, -0.707106709f)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, -0.693147123f)] // value: -(ln(2)) + [InlineData(-0.636619772f, -0.636619687f)] // value: -(2 / pi) + [InlineData(-0.434294482f, -0.434294462f)] // value: -(log10(e)) + [InlineData(-0.318309886f, -0.318309844f)] // value: -(1 / pi) + [InlineData(-0.0f, float.Epsilon)] + [InlineData( float.NaN, float.NaN)] + [InlineData( 0.0f, float.Epsilon)] + [InlineData( 0.318309886f, 0.318309903f)] // value: (1 / pi) + [InlineData( 0.434294482f, 0.434294522f)] // value: (log10(e)) + [InlineData( 0.636619772f, 0.636619806f)] // value: (2 / pi) + [InlineData( 0.693147181f, 0.693147242f)] // value: (ln(2)) + [InlineData( 0.707106781f, 0.707106829f)] // value: (1 / sqrt(2)) + [InlineData( 0.785398163f, 0.785398245f)] // value: (pi / 4) + [InlineData( 1.0f, 1.00000012f)] + [InlineData( 1.12837917f, 1.12837934f)] // value: (2 / sqrt(pi)) + [InlineData( 1.41421356f, 1.41421366f)] // value: (sqrt(2)) + [InlineData( 1.44269504f, 1.44269514f)] // value: (log2(e)) + [InlineData( 1.57079633f, 1.57079649f)] // value: (pi / 2) + [InlineData( 2.30258509f, 2.30258536f)] // value: (ln(10)) + [InlineData( 2.71828183f, 2.71828198f)] // value: (e) + [InlineData( 3.14159265f, 3.14159298f)] // value: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity)] + public static void BitIncrement(float value, float expectedResult) + { + AssertEqual(expectedResult, MathF.BitIncrement(value), 0.0f); + } + [Theory] [InlineData( float.NegativeInfinity, float.NegativeInfinity, 0.0f)] [InlineData(-3.14159265f, -1.46459189f, CrossPlatformMachineEpsilon * 10)] // value: -(pi) @@ -639,6 +717,61 @@ public static void Ceiling(float value, float expectedResult, float allowedVaria AssertEqual(expectedResult, MathF.Ceiling(value), allowedVariance); } + [Theory] + [InlineData( float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity)] + [InlineData( float.NegativeInfinity, -3.14159265f, float.NegativeInfinity)] + [InlineData( float.NegativeInfinity, -0.0f, float.NegativeInfinity)] + [InlineData( float.NegativeInfinity, float.NaN, float.NegativeInfinity)] + [InlineData( float.NegativeInfinity, 0.0f, float.PositiveInfinity)] + [InlineData( float.NegativeInfinity, 3.14159265f, float.PositiveInfinity)] + [InlineData( float.NegativeInfinity, float.PositiveInfinity, float.PositiveInfinity)] + [InlineData(-3.14159265f, float.NegativeInfinity, -3.14159265f)] + [InlineData(-3.14159265f, -3.14159265f, -3.14159265f)] + [InlineData(-3.14159265f, -0.0f, -3.14159265f)] + [InlineData(-3.14159265f, float.NaN, -3.14159265f)] + [InlineData(-3.14159265f, 0.0f, 3.14159265f)] + [InlineData(-3.14159265f, 3.14159265f, 3.14159265f)] + [InlineData(-3.14159265f, float.PositiveInfinity, 3.14159265f)] + [InlineData(-0.0f, float.NegativeInfinity, -0.0f)] + [InlineData(-0.0f, -3.14159265f, -0.0f)] + [InlineData(-0.0f, -0.0f, -0.0f)] + [InlineData(-0.0f, float.NaN, -0.0f)] + [InlineData(-0.0f, 0.0f, 0.0f)] + [InlineData(-0.0f, 3.14159265f, 0.0f)] + [InlineData(-0.0f, float.PositiveInfinity, 0.0f)] + [InlineData( float.NaN, float.NegativeInfinity, float.NaN)] + [InlineData( float.NaN, -3.14159265f, float.NaN)] + [InlineData( float.NaN, -0.0f, float.NaN)] + [InlineData( float.NaN, float.NaN, float.NaN)] + [InlineData( float.NaN, 0.0f, float.NaN)] + [InlineData( float.NaN, 3.14159265f, float.NaN)] + [InlineData( float.NaN, float.PositiveInfinity, float.NaN)] + [InlineData( 0.0f, float.NegativeInfinity, -0.0f)] + [InlineData( 0.0f, -3.14159265f, -0.0f)] + [InlineData( 0.0f, -0.0f, -0.0f)] + [InlineData( 0.0f, float.NaN, -0.0f)] + [InlineData( 0.0f, 0.0f, 0.0f)] + [InlineData( 0.0f, 3.14159265f, 0.0f)] + [InlineData( 0.0f, float.PositiveInfinity, 0.0f)] + [InlineData( 3.14159265f, float.NegativeInfinity, -3.14159265f)] + [InlineData( 3.14159265f, -3.14159265f, -3.14159265f)] + [InlineData( 3.14159265f, -0.0f, -3.14159265f)] + [InlineData( 3.14159265f, float.NaN, -3.14159265f)] + [InlineData( 3.14159265f, 0.0f, 3.14159265f)] + [InlineData( 3.14159265f, 3.14159265f, 3.14159265f)] + [InlineData( 3.14159265f, float.PositiveInfinity, 3.14159265f)] + [InlineData( float.PositiveInfinity, float.NegativeInfinity, float.NegativeInfinity)] + [InlineData( float.PositiveInfinity, -3.14159265f, float.NegativeInfinity)] + [InlineData( float.PositiveInfinity, -0.0f, float.NegativeInfinity)] + [InlineData( float.PositiveInfinity, float.NaN, float.NegativeInfinity)] + [InlineData( float.PositiveInfinity, 0.0f, float.PositiveInfinity)] + [InlineData( float.PositiveInfinity, 3.14159265f, float.PositiveInfinity)] + [InlineData( float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity)] + public static void CopySign(float x, float y, float expectedResult) + { + AssertEqual(expectedResult, MathF.CopySign(x, y), 0.0f); + } + [Theory] [InlineData( float.NegativeInfinity, float.NaN, 0.0f)] [InlineData(-3.14159265f, -1.0f, CrossPlatformMachineEpsilon * 10)] // value: -(pi) @@ -795,6 +928,78 @@ public static void Floor(float value, float expectedResult, float allowedVarianc AssertEqual(expectedResult, MathF.Floor(value), allowedVariance); } + [Theory] + [InlineData( float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity, float.NaN)] + [InlineData( float.NegativeInfinity, -0.0f, float.NegativeInfinity, float.NaN)] + [InlineData( float.NegativeInfinity, -0.0f, -3.14159265f, float.NaN)] + [InlineData( float.NegativeInfinity, -0.0f, -0.0f, float.NaN)] + [InlineData( float.NegativeInfinity, -0.0f, float.NaN, float.NaN)] + [InlineData( float.NegativeInfinity, -0.0f, 0.0f, float.NaN)] + [InlineData( float.NegativeInfinity, -0.0f, 3.14159265f, float.NaN)] + [InlineData( float.NegativeInfinity, -0.0f, float.PositiveInfinity, float.NaN)] + [InlineData( float.NegativeInfinity, 0.0f, float.NegativeInfinity, float.NaN)] + [InlineData( float.NegativeInfinity, 0.0f, -3.14159265f, float.NaN)] + [InlineData( float.NegativeInfinity, 0.0f, -0.0f, float.NaN)] + [InlineData( float.NegativeInfinity, 0.0f, float.NaN, float.NaN)] + [InlineData( float.NegativeInfinity, 0.0f, 0.0f, float.NaN)] + [InlineData( float.NegativeInfinity, 0.0f, 3.14159265f, float.NaN)] + [InlineData( float.NegativeInfinity, 0.0f, float.PositiveInfinity, float.NaN)] + [InlineData( float.NegativeInfinity, float.PositiveInfinity, float.PositiveInfinity, float.NaN)] + [InlineData(-1e38f, 2.0f, 1e38f, -1e38f)] + [InlineData(-1e38f, 2.0f, float.PositiveInfinity, float.PositiveInfinity)] + [InlineData(-5, 4, -3, -23)] + [InlineData(-0.0f, float.NegativeInfinity, float.NegativeInfinity, float.NaN)] + [InlineData(-0.0f, float.NegativeInfinity, -3.14159265f, float.NaN)] + [InlineData(-0.0f, float.NegativeInfinity, -0.0f, float.NaN)] + [InlineData(-0.0f, float.NegativeInfinity, float.NaN, float.NaN)] + [InlineData(-0.0f, float.NegativeInfinity, 0.0f, float.NaN)] + [InlineData(-0.0f, float.NegativeInfinity, 3.14159265f, float.NaN)] + [InlineData(-0.0f, float.NegativeInfinity, float.PositiveInfinity, float.NaN)] + [InlineData(-0.0f, float.PositiveInfinity, float.NegativeInfinity, float.NaN)] + [InlineData(-0.0f, float.PositiveInfinity, -3.14159265f, float.NaN)] + [InlineData(-0.0f, float.PositiveInfinity, -0.0f, float.NaN)] + [InlineData(-0.0f, float.PositiveInfinity, float.NaN, float.NaN)] + [InlineData(-0.0f, float.PositiveInfinity, 0.0f, float.NaN)] + [InlineData(-0.0f, float.PositiveInfinity, 3.14159265f, float.NaN)] + [InlineData(-0.0f, float.PositiveInfinity, float.PositiveInfinity, float.NaN)] + [InlineData( 0.0f, float.NegativeInfinity, float.NegativeInfinity, float.NaN)] + [InlineData( 0.0f, float.NegativeInfinity, -3.14159265f, float.NaN)] + [InlineData( 0.0f, float.NegativeInfinity, -0.0f, float.NaN)] + [InlineData( 0.0f, float.NegativeInfinity, float.NaN, float.NaN)] + [InlineData( 0.0f, float.NegativeInfinity, 0.0f, float.NaN)] + [InlineData( 0.0f, float.NegativeInfinity, 3.14159265f, float.NaN)] + [InlineData( 0.0f, float.NegativeInfinity, float.PositiveInfinity, float.NaN)] + [InlineData( 0.0f, float.PositiveInfinity, float.NegativeInfinity, float.NaN)] + [InlineData( 0.0f, float.PositiveInfinity, -3.14159265f, float.NaN)] + [InlineData( 0.0f, float.PositiveInfinity, -0.0f, float.NaN)] + [InlineData( 0.0f, float.PositiveInfinity, float.NaN, float.NaN)] + [InlineData( 0.0f, float.PositiveInfinity, 0.0f, float.NaN)] + [InlineData( 0.0f, float.PositiveInfinity, 3.14159265f, float.NaN)] + [InlineData( 0.0f, float.PositiveInfinity, float.PositiveInfinity, float.NaN)] + [InlineData( 5, 4, 3, 23)] + [InlineData( 1e38f, 2.0f, -1e38f, 1e38f)] + [InlineData( 1e38f, 2.0f, float.NegativeInfinity, float.NegativeInfinity)] + [InlineData( float.PositiveInfinity, float.NegativeInfinity, float.PositiveInfinity, float.NaN)] + [InlineData( float.PositiveInfinity, -0.0f, float.NegativeInfinity, float.NaN)] + [InlineData( float.PositiveInfinity, -0.0f, -3.14159265f, float.NaN)] + [InlineData( float.PositiveInfinity, -0.0f, -0.0f, float.NaN)] + [InlineData( float.PositiveInfinity, -0.0f, float.NaN, float.NaN)] + [InlineData( float.PositiveInfinity, -0.0f, 0.0f, float.NaN)] + [InlineData( float.PositiveInfinity, -0.0f, 3.14159265f, float.NaN)] + [InlineData( float.PositiveInfinity, -0.0f, float.PositiveInfinity, float.NaN)] + [InlineData( float.PositiveInfinity, 0.0f, float.NegativeInfinity, float.NaN)] + [InlineData( float.PositiveInfinity, 0.0f, -3.14159265f, float.NaN)] + [InlineData( float.PositiveInfinity, 0.0f, -0.0f, float.NaN)] + [InlineData( float.PositiveInfinity, 0.0f, float.NaN, float.NaN)] + [InlineData( float.PositiveInfinity, 0.0f, 0.0f, float.NaN)] + [InlineData( float.PositiveInfinity, 0.0f, 3.14159265f, float.NaN)] + [InlineData( float.PositiveInfinity, 0.0f, float.PositiveInfinity, float.NaN)] + [InlineData( float.PositiveInfinity, float.PositiveInfinity, float.NegativeInfinity, float.NaN)] + public static void FusedMultiplyAdd(float x, float y, float z, float expectedResult) + { + AssertEqual(expectedResult, MathF.FusedMultiplyAdd(x, y, z), 0.0f); + } + [Fact] public static void IEEERemainder() { @@ -810,6 +1015,46 @@ public static void IEEERemainder() AssertEqual(-1.4f, MathF.IEEERemainder(-17.8f, -4.1f), CrossPlatformMachineEpsilon * 10); } + [Theory] + [InlineData( float.NegativeInfinity, unchecked((int)(0x7FFFFFFF)))] + [InlineData(-0.0f, unchecked((int)(0x80000000)))] + [InlineData( float.NaN, unchecked((int)(0x7FFFFFFF)))] + [InlineData( 0.0f, unchecked((int)(0x80000000)))] + [InlineData( 0.113314732f, -4)] + [InlineData( 0.151955223f, -3)] + [InlineData( 0.202699566f, -3)] + [InlineData( 0.336622537f, -2)] + [InlineData( 0.367879441f, -2)] + [InlineData( 0.375214227f, -2)] + [InlineData( 0.457429347f, -2)] + [InlineData( 0.5f, -1)] + [InlineData( 0.580191810f, -1)] + [InlineData( 0.612547327f, -1)] + [InlineData( 0.618503138f, -1)] + [InlineData( 0.643218242f, -1)] + [InlineData( 0.740055574f, -1)] + [InlineData( 0.802008879f, -1)] + [InlineData( 1.0f, 0)] + [InlineData( 1.24686899f, 0)] + [InlineData( 1.35124987f, 0)] + [InlineData( 1.55468228f, 0)] + [InlineData( 1.61680667f, 0)] + [InlineData( 1.63252692f, 0)] + [InlineData( 1.72356793f, 0)] + [InlineData( 2.0f, 1)] + [InlineData( 2.18612996f, 1)] + [InlineData( 2.66514414f, 1)] + [InlineData( 2.71828183f, 1)] + [InlineData( 2.97068642f, 1)] + [InlineData( 4.93340967f, 2)] + [InlineData( 6.58088599f, 2)] + [InlineData( 8.82497783f, 3)] + [InlineData( float.PositiveInfinity, unchecked((int)(0x7FFFFFFF)))] + public static void ILogB(float value, int expectedResult) + { + Assert.Equal(expectedResult, MathF.ILogB(value)); + } + [Theory] [InlineData( float.NegativeInfinity, float.NaN, 0.0f)] [InlineData(-3.14159265f, float.NaN, 0.0f)] // value: -(pi) @@ -868,6 +1113,47 @@ public static void LogWithBase() Assert.Equal(float.NaN, MathF.Log(float.NegativeInfinity, 3.0f)); } + [Theory] + [InlineData( float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(-0.113314732f, float.NaN, 0.0f)] + [InlineData(-0.0f, float.NegativeInfinity, 0.0f)] + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData( 0.0f, float.NegativeInfinity, 0.0f)] + [InlineData( 0.113314732f, -3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi) + [InlineData( 0.151955223f, -2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: -(e) + [InlineData( 0.202699566f, -2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: -(ln(10)) + [InlineData( 0.336622537f, -1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData( 0.367879441f, -1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: -(log2(e)) + [InlineData( 0.375214227f, -1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: -(sqrt(2)) + [InlineData( 0.457429347f, -1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: -(2 / sqrt(pi)) + [InlineData( 0.5f, -1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 0.580191810f, -0.785398163f, CrossPlatformMachineEpsilon)] // expected: -(pi / 4) + [InlineData( 0.612547327f, -0.707106781f, CrossPlatformMachineEpsilon)] // expected: -(1 / sqrt(2)) + [InlineData( 0.618503138f, -0.693147181f, CrossPlatformMachineEpsilon)] // expected: -(ln(2)) + [InlineData( 0.643218242f, -0.636619772f, CrossPlatformMachineEpsilon)] // expected: -(2 / pi) + [InlineData( 0.740055574f, -0.434294482f, CrossPlatformMachineEpsilon)] // expected: -(log10(e)) + [InlineData( 0.802008879f, -0.318309886f, CrossPlatformMachineEpsilon)] // expected: -(1 / pi) + [InlineData( 1, 0.0f, 0.0f)] + [InlineData( 1.24686899f, 0.318309886f, CrossPlatformMachineEpsilon)] // expected: (1 / pi) + [InlineData( 1.35124987f, 0.434294482f, CrossPlatformMachineEpsilon)] // expected: (log10(e)) + [InlineData( 1.55468228f, 0.636619772f, CrossPlatformMachineEpsilon)] // expected: (2 / pi) + [InlineData( 1.61680667f, 0.693147181f, CrossPlatformMachineEpsilon)] // expected: (ln(2)) + [InlineData( 1.63252692f, 0.707106781f, CrossPlatformMachineEpsilon)] // expected: (1 / sqrt(2)) + [InlineData( 1.72356793f, 0.785398163f, CrossPlatformMachineEpsilon)] // expected: (pi / 4) + [InlineData( 2, 1.0f, CrossPlatformMachineEpsilon * 10)] // value: (e) + [InlineData( 2.18612996f, 1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: (2 / sqrt(pi)) + [InlineData( 2.66514414f, 1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: (sqrt(2)) + [InlineData( 2.71828183f, 1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: (log2(e)) + [InlineData( 2.97068642f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData( 4.93340967f, 2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: (ln(10)) + [InlineData( 6.58088599f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: (e) + [InlineData( 8.82497783f, 3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Log2(float value, float expectedResult, float allowedVariance) + { + AssertEqual(expectedResult, MathF.Log2(value), allowedVariance); + } + [Theory] [InlineData( float.NegativeInfinity, float.NaN, 0.0f)] [InlineData(-3.14159265f, float.NaN, 0.0f)] // value: -(pi) @@ -918,22 +1204,52 @@ public static void Log10(float value, float expectedResult, float allowedVarianc [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.PositiveInfinity)] public static void Max(float x, float y, float expectedResult) { - AssertEqual(expectedResult, Math.Max(x, y), 0.0f); + AssertEqual(expectedResult, MathF.Max(x, y), 0.0f); + } + + [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, -3.0f)] + [InlineData(3.0f, -2.0f, 3.0f)] + [InlineData(float.PositiveInfinity, float.NaN, float.PositiveInfinity)] + public static void MaxMagnitude(float x, float y, float expectedResult) + { + AssertEqual(expectedResult, MathF.MaxMagnitude(x, y), 0.0f); } [Theory] [InlineData(float.NegativeInfinity, float.PositiveInfinity, float.NegativeInfinity)] [InlineData(float.MinValue, float.MaxValue, float.MinValue)] [InlineData(float.NaN, float.NaN, float.NaN)] - [InlineData(3.0, -2.0, -2.0)] + [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.PositiveInfinity)] public static void Min(float x, float y, float expectedResult) { - AssertEqual(expectedResult, Math.Min(x, y), 0.0f); + AssertEqual(expectedResult, MathF.Min(x, y), 0.0f); + } + + [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, 2.0f)] + [InlineData(3.0f, -2.0f, -2.0f)] + [InlineData(float.PositiveInfinity, float.NaN, float.PositiveInfinity)] + public static void MinMagnitude(float x, float y, float expectedResult) + { + AssertEqual(expectedResult, MathF.MinMagnitude(x, y), 0.0f); } [Theory] @@ -1134,6 +1450,47 @@ public static void Round_Digits() Assert.Equal(float.NegativeInfinity, MathF.Round(float.NegativeInfinity, 3, MidpointRounding.AwayFromZero)); } + [Theory] + [InlineData( float.NegativeInfinity, unchecked((int)(0x7FFFFFFF)), float.NegativeInfinity, 0)] + [InlineData(-0.113314732f, -3, -0.0141643415f, CrossPlatformMachineEpsilon / 10)] + [InlineData(-0.0f, unchecked((int)(0x80000000)), -0.0f, 0)] + [InlineData( float.NaN, unchecked((int)(0x7FFFFFFF)), float.NaN, 0)] + [InlineData( 0, unchecked((int)(0x80000000)), 0, 0)] + [InlineData( 0.113314732f, -4, 0.00708217081f, CrossPlatformMachineEpsilon / 100)] + [InlineData( 0.151955223f, -3, 0.0189944021f, CrossPlatformMachineEpsilon / 10)] + [InlineData( 0.202699566f, -3, 0.0253374465f, CrossPlatformMachineEpsilon / 10)] + [InlineData( 0.336622537f, -2, 0.084155634f, CrossPlatformMachineEpsilon / 10)] + [InlineData( 0.367879441f, -2, 0.0919698626f, CrossPlatformMachineEpsilon / 10)] + [InlineData( 0.375214227f, -2, 0.0938035548f, CrossPlatformMachineEpsilon / 10)] + [InlineData( 0.457429347f, -2, 0.114357337f, CrossPlatformMachineEpsilon)] + [InlineData( 0.5f, -1, 0.25f, CrossPlatformMachineEpsilon)] + [InlineData( 0.580191810f, -1, 0.290095896f, CrossPlatformMachineEpsilon)] + [InlineData( 0.612547327f, -1, 0.306273669f, CrossPlatformMachineEpsilon)] + [InlineData( 0.618503138f, -1, 0.309251577f, CrossPlatformMachineEpsilon)] + [InlineData( 0.643218242f, -1, 0.321609110f, CrossPlatformMachineEpsilon)] + [InlineData( 0.740055574f, -1, 0.370027781f, CrossPlatformMachineEpsilon)] + [InlineData( 0.802008879f, -1, 0.401004434f, CrossPlatformMachineEpsilon)] + [InlineData( 1, 0, 1, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.24686899f, 0, 1.24686899f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.35124987f, 0, 1.35124987f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.55468228f, 0, 1.55468228f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.61680667f, 0, 1.61680667f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.63252692f, 0, 1.63252692f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.72356793f, 0, 1.72356793f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2, 1, 4, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.18612996f, 1, 4.37225992f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.66514414f, 1, 5.33028829f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.71828183f, 1, 5.43656366f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.97068642f, 1, 5.94137285f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 4.93340967f, 2, 19.7336387f, CrossPlatformMachineEpsilon * 100)] + [InlineData( 6.58088599f, 2, 26.3235440f, CrossPlatformMachineEpsilon * 100)] + [InlineData( 8.82497783f, 3, 70.5998226f, CrossPlatformMachineEpsilon * 100)] + [InlineData( float.PositiveInfinity, unchecked((int)(0x7FFFFFFF)), float.PositiveInfinity, 0)] + public static void ScaleB(float x, int n, float expectedResult, float allowedVariance) + { + AssertEqual(expectedResult, MathF.ScaleB(x, n), allowedVariance); + } + [Fact] public static void Sign() { diff --git a/src/System.Runtime.Extensions/tests/System/MathTests.netcoreapp.cs b/src/System.Runtime.Extensions/tests/System/MathTests.netcoreapp.cs index d62b0268626c..1ae8ff9e7ff0 100644 --- a/src/System.Runtime.Extensions/tests/System/MathTests.netcoreapp.cs +++ b/src/System.Runtime.Extensions/tests/System/MathTests.netcoreapp.cs @@ -149,6 +149,84 @@ public static void Atanh(double value, double expectedResult, double allowedVari AssertEqual(expectedResult, Math.Atanh(value), allowedVariance); } + [Theory] + [InlineData( double.NegativeInfinity, double.NegativeInfinity)] + [InlineData(-3.1415926535897932, -3.1415926535897936)] // value: -(pi) + [InlineData(-2.7182818284590452, -2.7182818284590455)] // value: -(e) + [InlineData(-2.3025850929940457, -2.3025850929940463)] // value: -(ln(10)) + [InlineData(-1.5707963267948966, -1.5707963267948968)] // value: -(pi / 2) + [InlineData(-1.4426950408889634, -1.4426950408889636)] // value: -(log2(e)) + [InlineData(-1.4142135623730950, -1.4142135623730951)] // value: -(sqrt(2)) + [InlineData(-1.1283791670955126, -1.1283791670955128)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0, -1.0000000000000002)] + [InlineData(-0.78539816339744831, -0.78539816339744839)] // value: -(pi / 4) + [InlineData(-0.70710678118654752, -0.70710678118654768)] // value: -(1 / sqrt(2)) + [InlineData(-0.69314718055994531, -0.69314718055994540)] // value: -(ln(2)) + [InlineData(-0.63661977236758134, -0.63661977236758149)] // value: -(2 / pi) + [InlineData(-0.43429448190325183, -0.43429448190325187)] // value: -(log10(e)) + [InlineData(-0.31830988618379067, -0.31830988618379075)] // value: -(1 / pi) + [InlineData(-0.0, -double.Epsilon)] + [InlineData( double.NaN, double.NaN)] + [InlineData( 0.0, -double.Epsilon)] + [InlineData( 0.31830988618379067, 0.31830988618379064)] // value: (1 / pi) + [InlineData( 0.43429448190325183, 0.43429448190325176)] // value: (log10(e)) + [InlineData( 0.63661977236758134, 0.63661977236758127)] // value: (2 / pi) + [InlineData( 0.69314718055994531, 0.69314718055994518)] // value: (ln(2)) + [InlineData( 0.70710678118654752, 0.70710678118654746)] // value: (1 / sqrt(2)) + [InlineData( 0.78539816339744831, 0.78539816339744817)] // value: (pi / 4) + [InlineData( 1.0, 0.99999999999999989)] + [InlineData( 1.1283791670955126, 1.1283791670955123)] // value: (2 / sqrt(pi)) + [InlineData( 1.4142135623730950, 1.4142135623730947)] // value: (sqrt(2)) + [InlineData( 1.4426950408889634, 1.4426950408889632)] // value: (log2(e)) + [InlineData( 1.5707963267948966, 1.5707963267948963)] // value: (pi / 2) + [InlineData( 2.3025850929940457, 2.3025850929940455)] // value: (ln(10)) + [InlineData( 2.7182818284590452, 2.7182818284590446)] // value: (e) + [InlineData( 3.1415926535897932, 3.1415926535897927)] // value: (pi) + [InlineData( double.PositiveInfinity, double.MaxValue)] + public static void BitDecrement(double value, double expectedResult) + { + AssertEqual(expectedResult, Math.BitDecrement(value), 0.0); + } + + [Theory] + [InlineData( double.NegativeInfinity, double.MinValue)] + [InlineData(-3.1415926535897932, -3.1415926535897927)] // value: -(pi) + [InlineData(-2.7182818284590452, -2.7182818284590446)] // value: -(e) + [InlineData(-2.3025850929940457, -2.3025850929940455)] // value: -(ln(10)) + [InlineData(-1.5707963267948966, -1.5707963267948963)] // value: -(pi / 2) + [InlineData(-1.4426950408889634, -1.4426950408889632)] // value: -(log2(e)) + [InlineData(-1.4142135623730950, -1.4142135623730947)] // value: -(sqrt(2)) + [InlineData(-1.1283791670955126, -1.1283791670955123)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0, -0.99999999999999989)] + [InlineData(-0.78539816339744831, -0.78539816339744817)] // value: -(pi / 4) + [InlineData(-0.70710678118654752, -0.70710678118654746)] // value: -(1 / sqrt(2)) + [InlineData(-0.69314718055994531, -0.69314718055994518)] // value: -(ln(2)) + [InlineData(-0.63661977236758134, -0.63661977236758127)] // value: -(2 / pi) + [InlineData(-0.43429448190325183, -0.43429448190325176)] // value: -(log10(e)) + [InlineData(-0.31830988618379067, -0.31830988618379064)] // value: -(1 / pi) + [InlineData(-0.0, double.Epsilon)] + [InlineData( double.NaN, double.NaN)] + [InlineData( 0.0, double.Epsilon)] + [InlineData( 0.31830988618379067, 0.31830988618379075)] // value: (1 / pi) + [InlineData( 0.43429448190325183, 0.43429448190325187)] // value: (log10(e)) + [InlineData( 0.63661977236758134, 0.63661977236758149)] // value: (2 / pi) + [InlineData( 0.69314718055994531, 0.69314718055994540)] // value: (ln(2)) + [InlineData( 0.70710678118654752, 0.70710678118654768)] // value: (1 / sqrt(2)) + [InlineData( 0.78539816339744831, 0.78539816339744839)] // value: (pi / 4) + [InlineData( 1.0, 1.0000000000000002 )] + [InlineData( 1.1283791670955126, 1.1283791670955128 )] // value: (2 / sqrt(pi)) + [InlineData( 1.4142135623730950, 1.4142135623730951 )] // value: (sqrt(2)) + [InlineData( 1.4426950408889634, 1.4426950408889636 )] // value: (log2(e)) + [InlineData( 1.5707963267948966, 1.5707963267948968 )] // value: (pi / 2) + [InlineData( 2.3025850929940457, 2.3025850929940463 )] // value: (ln(10)) + [InlineData( 2.7182818284590452, 2.7182818284590455 )] // value: (e) + [InlineData( 3.1415926535897932, 3.1415926535897936 )] // value: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity)] + public static void BitIncrement(double value, double expectedResult) + { + AssertEqual(expectedResult, Math.BitIncrement(value), 0.0); + } + [Theory] [InlineData( double.NegativeInfinity, double.NegativeInfinity, 0.0)] [InlineData(-3.1415926535897932, -1.4645918875615233, CrossPlatformMachineEpsilon * 10)] // value: -(pi) @@ -305,5 +383,280 @@ public static void Clamp_MinGreaterThanMax_ThrowsArgumentException() AssertExtensions.Throws(null, () => Math.Clamp((double)1, (double)2, (double)1)); AssertExtensions.Throws(null, () => Math.Clamp((decimal)1, (decimal)2, (decimal)1)); } + + [Theory] + [InlineData( double.NegativeInfinity, double.NegativeInfinity, double.NegativeInfinity)] + [InlineData( double.NegativeInfinity, -3.1415926535897932, double.NegativeInfinity)] + [InlineData( double.NegativeInfinity, -0.0, double.NegativeInfinity)] + [InlineData( double.NegativeInfinity, double.NaN, double.NegativeInfinity)] + [InlineData( double.NegativeInfinity, 0.0, double.PositiveInfinity)] + [InlineData( double.NegativeInfinity, 3.1415926535897932, double.PositiveInfinity)] + [InlineData( double.NegativeInfinity, double.PositiveInfinity, double.PositiveInfinity)] + [InlineData(-3.1415926535897932, double.NegativeInfinity, -3.1415926535897932)] + [InlineData(-3.1415926535897932, -3.1415926535897932, -3.1415926535897932)] + [InlineData(-3.1415926535897932, -0.0, -3.1415926535897932)] + [InlineData(-3.1415926535897932, double.NaN, -3.1415926535897932)] + [InlineData(-3.1415926535897932, 0.0, 3.1415926535897932)] + [InlineData(-3.1415926535897932, 3.1415926535897932, 3.1415926535897932)] + [InlineData(-3.1415926535897932, double.PositiveInfinity, 3.1415926535897932)] + [InlineData(-0.0, double.NegativeInfinity, -0.0)] + [InlineData(-0.0, -3.1415926535897932, -0.0)] + [InlineData(-0.0, -0.0, -0.0)] + [InlineData(-0.0, double.NaN, -0.0)] + [InlineData(-0.0, 0.0, 0.0)] + [InlineData(-0.0, 3.1415926535897932, 0.0)] + [InlineData(-0.0, double.PositiveInfinity, 0.0)] + [InlineData( double.NaN, double.NegativeInfinity, double.NaN)] + [InlineData( double.NaN, -3.1415926535897932, double.NaN)] + [InlineData( double.NaN, -0.0, double.NaN)] + [InlineData( double.NaN, double.NaN, double.NaN)] + [InlineData( double.NaN, 0.0, double.NaN)] + [InlineData( double.NaN, 3.1415926535897932, double.NaN)] + [InlineData( double.NaN, double.PositiveInfinity, double.NaN)] + [InlineData( 0.0, double.NegativeInfinity, -0.0)] + [InlineData( 0.0, -3.1415926535897932, -0.0)] + [InlineData( 0.0, -0.0, -0.0)] + [InlineData( 0.0, double.NaN, -0.0)] + [InlineData( 0.0, 0.0, 0.0)] + [InlineData( 0.0, 3.1415926535897932, 0.0)] + [InlineData( 0.0, double.PositiveInfinity, 0.0)] + [InlineData( 3.1415926535897932, double.NegativeInfinity, -3.1415926535897932)] + [InlineData( 3.1415926535897932, -3.1415926535897932, -3.1415926535897932)] + [InlineData( 3.1415926535897932, -0.0, -3.1415926535897932)] + [InlineData( 3.1415926535897932, double.NaN, -3.1415926535897932)] + [InlineData( 3.1415926535897932, 0.0, 3.1415926535897932)] + [InlineData( 3.1415926535897932, 3.1415926535897932, 3.1415926535897932)] + [InlineData( 3.1415926535897932, double.PositiveInfinity, 3.1415926535897932)] + [InlineData( double.PositiveInfinity, double.NegativeInfinity, double.NegativeInfinity)] + [InlineData( double.PositiveInfinity, -3.1415926535897932, double.NegativeInfinity)] + [InlineData( double.PositiveInfinity, -0.0, double.NegativeInfinity)] + [InlineData( double.PositiveInfinity, double.NaN, double.NegativeInfinity)] + [InlineData( double.PositiveInfinity, 0.0, double.PositiveInfinity)] + [InlineData( double.PositiveInfinity, 3.1415926535897932, double.PositiveInfinity)] + [InlineData( double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity)] + public static void CopySign(double x, double y, double expectedResult) + { + AssertEqual(expectedResult, Math.CopySign(x, y), 0.0); + } + + [Theory] + [InlineData( double.NegativeInfinity, double.NegativeInfinity, double.NegativeInfinity, double.NaN)] + [InlineData( double.NegativeInfinity, -0.0, double.NegativeInfinity, double.NaN)] + [InlineData( double.NegativeInfinity, -0.0, -3.1415926535897932, double.NaN)] + [InlineData( double.NegativeInfinity, -0.0, -0.0, double.NaN)] + [InlineData( double.NegativeInfinity, -0.0, double.NaN, double.NaN)] + [InlineData( double.NegativeInfinity, -0.0, 0.0, double.NaN)] + [InlineData( double.NegativeInfinity, -0.0, 3.1415926535897932, double.NaN)] + [InlineData( double.NegativeInfinity, -0.0, double.PositiveInfinity, double.NaN)] + [InlineData( double.NegativeInfinity, 0.0, double.NegativeInfinity, double.NaN)] + [InlineData( double.NegativeInfinity, 0.0, -3.1415926535897932, double.NaN)] + [InlineData( double.NegativeInfinity, 0.0, -0.0, double.NaN)] + [InlineData( double.NegativeInfinity, 0.0, double.NaN, double.NaN)] + [InlineData( double.NegativeInfinity, 0.0, 0.0, double.NaN)] + [InlineData( double.NegativeInfinity, 0.0, 3.1415926535897932, double.NaN)] + [InlineData( double.NegativeInfinity, 0.0, double.PositiveInfinity, double.NaN)] + [InlineData( double.NegativeInfinity, double.PositiveInfinity, double.PositiveInfinity, double.NaN)] + [InlineData(-1e308, 2.0, 1e308, -1e308)] + [InlineData(-1e308, 2.0, double.PositiveInfinity, double.PositiveInfinity)] + [InlineData(-5, 4, -3, -23)] + [InlineData(-0.0, double.NegativeInfinity, double.NegativeInfinity, double.NaN)] + [InlineData(-0.0, double.NegativeInfinity, -3.1415926535897932, double.NaN)] + [InlineData(-0.0, double.NegativeInfinity, -0.0, double.NaN)] + [InlineData(-0.0, double.NegativeInfinity, double.NaN, double.NaN)] + [InlineData(-0.0, double.NegativeInfinity, 0.0, double.NaN)] + [InlineData(-0.0, double.NegativeInfinity, 3.1415926535897932, double.NaN)] + [InlineData(-0.0, double.NegativeInfinity, double.PositiveInfinity, double.NaN)] + [InlineData(-0.0, double.PositiveInfinity, double.NegativeInfinity, double.NaN)] + [InlineData(-0.0, double.PositiveInfinity, -3.1415926535897932, double.NaN)] + [InlineData(-0.0, double.PositiveInfinity, -0.0, double.NaN)] + [InlineData(-0.0, double.PositiveInfinity, double.NaN, double.NaN)] + [InlineData(-0.0, double.PositiveInfinity, 0.0, double.NaN)] + [InlineData(-0.0, double.PositiveInfinity, 3.1415926535897932, double.NaN)] + [InlineData(-0.0, double.PositiveInfinity, double.PositiveInfinity, double.NaN)] + [InlineData( 0.0, double.NegativeInfinity, double.NegativeInfinity, double.NaN)] + [InlineData( 0.0, double.NegativeInfinity, -3.1415926535897932, double.NaN)] + [InlineData( 0.0, double.NegativeInfinity, -0.0, double.NaN)] + [InlineData( 0.0, double.NegativeInfinity, double.NaN, double.NaN)] + [InlineData( 0.0, double.NegativeInfinity, 0.0, double.NaN)] + [InlineData( 0.0, double.NegativeInfinity, 3.1415926535897932, double.NaN)] + [InlineData( 0.0, double.NegativeInfinity, double.PositiveInfinity, double.NaN)] + [InlineData( 0.0, double.PositiveInfinity, double.NegativeInfinity, double.NaN)] + [InlineData( 0.0, double.PositiveInfinity, -3.1415926535897932, double.NaN)] + [InlineData( 0.0, double.PositiveInfinity, -0.0, double.NaN)] + [InlineData( 0.0, double.PositiveInfinity, double.NaN, double.NaN)] + [InlineData( 0.0, double.PositiveInfinity, 0.0, double.NaN)] + [InlineData( 0.0, double.PositiveInfinity, 3.1415926535897932, double.NaN)] + [InlineData( 0.0, double.PositiveInfinity, double.PositiveInfinity, double.NaN)] + [InlineData( 5, 4, 3, 23)] + [InlineData( 1e308, 2.0, -1e308, 1e308)] + [InlineData( 1e308, 2.0, double.NegativeInfinity, double.NegativeInfinity)] + [InlineData( double.PositiveInfinity, double.NegativeInfinity, double.PositiveInfinity, double.NaN)] + [InlineData( double.PositiveInfinity, -0.0, double.NegativeInfinity, double.NaN)] + [InlineData( double.PositiveInfinity, -0.0, -3.1415926535897932, double.NaN)] + [InlineData( double.PositiveInfinity, -0.0, -0.0, double.NaN)] + [InlineData( double.PositiveInfinity, -0.0, double.NaN, double.NaN)] + [InlineData( double.PositiveInfinity, -0.0, 0.0, double.NaN)] + [InlineData( double.PositiveInfinity, -0.0, 3.1415926535897932, double.NaN)] + [InlineData( double.PositiveInfinity, -0.0, double.PositiveInfinity, double.NaN)] + [InlineData( double.PositiveInfinity, 0.0, double.NegativeInfinity, double.NaN)] + [InlineData( double.PositiveInfinity, 0.0, -3.1415926535897932, double.NaN)] + [InlineData( double.PositiveInfinity, 0.0, -0.0, double.NaN)] + [InlineData( double.PositiveInfinity, 0.0, double.NaN, double.NaN)] + [InlineData( double.PositiveInfinity, 0.0, 0.0, double.NaN)] + [InlineData( double.PositiveInfinity, 0.0, 3.1415926535897932, double.NaN)] + [InlineData( double.PositiveInfinity, 0.0, double.PositiveInfinity, double.NaN)] + [InlineData( double.PositiveInfinity, double.PositiveInfinity, double.NegativeInfinity, double.NaN)] + public static void FusedMultiplyAdd(double x, double y, double z, double expectedResult) + { + AssertEqual(expectedResult, Math.FusedMultiplyAdd(x, y, z), 0.0); + } + + [Theory] + [InlineData( double.NegativeInfinity, unchecked((int)(0x7FFFFFFF)))] + [InlineData(-0.0, unchecked((int)(0x80000000)))] + [InlineData( double.NaN, unchecked((int)(0x7FFFFFFF)))] + [InlineData( 0.0, unchecked((int)(0x80000000)))] + [InlineData( 0.11331473229676087, -4)] + [InlineData( 0.15195522325791297, -3)] + [InlineData( 0.20269956628651730, -3)] + [InlineData( 0.33662253682241906, -2)] + [InlineData( 0.36787944117144232, -2)] + [InlineData( 0.37521422724648177, -2)] + [InlineData( 0.45742934732229695, -2)] + [InlineData( 0.5, -1)] + [InlineData( 0.58019181037172444, -1)] + [InlineData( 0.61254732653606592, -1)] + [InlineData( 0.61850313780157598, -1)] + [InlineData( 0.64321824193300488, -1)] + [InlineData( 0.74005557395545179, -1)] + [InlineData( 0.80200887896145195, -1)] + [InlineData( 1, 0)] + [InlineData( 1.2468689889006383, 0)] + [InlineData( 1.3512498725672678, 0)] + [InlineData( 1.5546822754821001, 0)] + [InlineData( 1.6168066722416747, 0)] + [InlineData( 1.6325269194381528, 0)] + [InlineData( 1.7235679341273495, 0)] + [InlineData( 2, 1)] + [InlineData( 2.1861299583286618, 1)] + [InlineData( 2.6651441426902252, 1)] + [InlineData( 2.7182818284590452, 1)] + [InlineData( 2.9706864235520193, 1)] + [InlineData( 4.9334096679145963, 2)] + [InlineData( 6.5808859910179210, 2)] + [InlineData( 8.8249778270762876, 3)] + [InlineData( double.PositiveInfinity, unchecked((int)(0x7FFFFFFF)))] + public static void ILogB(double value, int expectedResult) + { + Assert.Equal(expectedResult, Math.ILogB(value)); + } + + [Theory] + [InlineData( double.NegativeInfinity, double.NaN, 0.0)] + [InlineData(-0.11331473229676087, double.NaN, 0.0)] + [InlineData(-0.0, double.NegativeInfinity, 0.0)] + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData( 0.0, double.NegativeInfinity, 0.0)] + [InlineData( 0.11331473229676087, -3.1415926535897932, CrossPlatformMachineEpsilon * 10)] // expected: -(pi) + [InlineData( 0.15195522325791297, -2.7182818284590452, CrossPlatformMachineEpsilon * 10)] // expected: -(e) + [InlineData( 0.20269956628651730, -2.3025850929940457, CrossPlatformMachineEpsilon * 10)] // expected: -(ln(10)) + [InlineData( 0.33662253682241906, -1.5707963267948966, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData( 0.36787944117144232, -1.4426950408889634, CrossPlatformMachineEpsilon * 10)] // expected: -(log2(e)) + [InlineData( 0.37521422724648177, -1.4142135623730950, CrossPlatformMachineEpsilon * 10)] // expected: -(sqrt(2)) + [InlineData( 0.45742934732229695, -1.1283791670955126, CrossPlatformMachineEpsilon * 10)] // expected: -(2 / sqrt(pi)) + [InlineData( 0.5, -1.0, CrossPlatformMachineEpsilon * 10)] + [InlineData( 0.58019181037172444, -0.78539816339744831, CrossPlatformMachineEpsilon)] // expected: -(pi / 4) + [InlineData( 0.61254732653606592, -0.70710678118654752, CrossPlatformMachineEpsilon)] // expected: -(1 / sqrt(2)) + [InlineData( 0.61850313780157598, -0.69314718055994531, CrossPlatformMachineEpsilon)] // expected: -(ln(2)) + [InlineData( 0.64321824193300488, -0.63661977236758134, CrossPlatformMachineEpsilon)] // expected: -(2 / pi) + [InlineData( 0.74005557395545179, -0.43429448190325183, CrossPlatformMachineEpsilon)] // expected: -(log10(e)) + [InlineData( 0.80200887896145195, -0.31830988618379067, CrossPlatformMachineEpsilon)] // expected: -(1 / pi) + [InlineData( 1, 0.0, 0.0)] + [InlineData( 1.2468689889006383, 0.31830988618379067, CrossPlatformMachineEpsilon)] // expected: (1 / pi) + [InlineData( 1.3512498725672678, 0.43429448190325183, CrossPlatformMachineEpsilon)] // expected: (log10(e)) + [InlineData( 1.5546822754821001, 0.63661977236758134, CrossPlatformMachineEpsilon)] // expected: (2 / pi) + [InlineData( 1.6168066722416747, 0.69314718055994531, CrossPlatformMachineEpsilon)] // expected: (ln(2)) + [InlineData( 1.6325269194381528, 0.70710678118654752, CrossPlatformMachineEpsilon)] // expected: (1 / sqrt(2)) + [InlineData( 1.7235679341273495, 0.78539816339744831, CrossPlatformMachineEpsilon)] // expected: (pi / 4) + [InlineData( 2, 1.0, CrossPlatformMachineEpsilon * 10)] // value: (e) + [InlineData( 2.1861299583286618, 1.1283791670955126, CrossPlatformMachineEpsilon * 10)] // expected: (2 / sqrt(pi)) + [InlineData( 2.6651441426902252, 1.4142135623730950, CrossPlatformMachineEpsilon * 10)] // expected: (sqrt(2)) + [InlineData( 2.7182818284590452, 1.4426950408889634, CrossPlatformMachineEpsilon * 10)] // expected: (log2(e)) + [InlineData( 2.9706864235520193, 1.5707963267948966, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData( 4.9334096679145963, 2.3025850929940457, CrossPlatformMachineEpsilon * 10)] // expected: (ln(10)) + [InlineData( 6.5808859910179210, 2.7182818284590452, CrossPlatformMachineEpsilon * 10)] // expected: (e) + [InlineData( 8.8249778270762876, 3.1415926535897932, CrossPlatformMachineEpsilon * 10)] // expected: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Log2(double value, double expectedResult, double allowedVariance) + { + AssertEqual(expectedResult, Math.Log2(value), allowedVariance); + } + + [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, -3.0)] + [InlineData(3.0, -2.0, 3.0)] + [InlineData(double.PositiveInfinity, double.NaN, double.PositiveInfinity)] + public static void MaxMagnitude(double x, double y, double expectedResult) + { + AssertEqual(expectedResult, Math.MaxMagnitude(x, y), 0.0); + } + + [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, 2.0)] + [InlineData(3.0, -2.0, -2.0)] + [InlineData(double.PositiveInfinity, double.NaN, double.PositiveInfinity)] + public static void MinMagnitude(double x, double y, double expectedResult) + { + AssertEqual(expectedResult, Math.MinMagnitude(x, y), 0.0); + } + + [Theory] + [InlineData( double.NegativeInfinity, unchecked((int)(0x7FFFFFFF)), double.NegativeInfinity, 0)] + [InlineData(-0.11331473229676087, -3, -0.014164341537095108, CrossPlatformMachineEpsilon / 10)] + [InlineData(-0.0, unchecked((int)(0x80000000)), -0.0, 0)] + [InlineData( double.NaN, unchecked((int)(0x7FFFFFFF)), double.NaN, 0)] + [InlineData( 0.0, unchecked((int)(0x80000000)), 0, 0)] + [InlineData( 0.11331473229676087, -4, 0.0070821707685475542, CrossPlatformMachineEpsilon / 100)] + [InlineData( 0.15195522325791297, -3, 0.018994402907239121, CrossPlatformMachineEpsilon / 10)] + [InlineData( 0.20269956628651730, -3, 0.025337445785814663, CrossPlatformMachineEpsilon / 10)] + [InlineData( 0.33662253682241906, -2, 0.084155634205604762, CrossPlatformMachineEpsilon / 10)] + [InlineData( 0.36787944117144232, -2, 0.091969860292860584, CrossPlatformMachineEpsilon / 10)] + [InlineData( 0.37521422724648177, -2, 0.093803556811620448, CrossPlatformMachineEpsilon / 10)] + [InlineData( 0.45742934732229695, -2, 0.11435733683057424, CrossPlatformMachineEpsilon)] + [InlineData( 0.5, -1, 0.25, CrossPlatformMachineEpsilon)] + [InlineData( 0.58019181037172444, -1, 0.2900959051858622, CrossPlatformMachineEpsilon)] + [InlineData( 0.61254732653606592, -1, 0.30627366326803296, CrossPlatformMachineEpsilon)] + [InlineData( 0.61850313780157598, -1, 0.30925156890078798, CrossPlatformMachineEpsilon)] + [InlineData( 0.64321824193300488, -1, 0.32160912096650246, CrossPlatformMachineEpsilon)] + [InlineData( 0.74005557395545179, -1, 0.37002778697772587, CrossPlatformMachineEpsilon)] + [InlineData( 0.80200887896145195, -1, 0.40100443948072595, CrossPlatformMachineEpsilon)] + [InlineData( 1, 0, 1, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.2468689889006383, 0, 1.2468689889006384, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.3512498725672678, 0, 1.3512498725672677, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.5546822754821001, 0, 1.5546822754821001, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.6168066722416747, 0, 1.6168066722416747, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.6325269194381528, 0, 1.6325269194381529, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.7235679341273495, 0, 1.7235679341273495, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2, 1, 4, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.1861299583286618, 1, 4.3722599166573239, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.6651441426902252, 1, 5.3302882853804503, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.7182818284590452, 1, 5.4365636569180902, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.9706864235520193, 1, 5.9413728471040388, CrossPlatformMachineEpsilon * 10)] + [InlineData( 4.9334096679145963, 2, 19.733638671658387, CrossPlatformMachineEpsilon * 100)] + [InlineData( 6.5808859910179210, 2, 26.323543964071686, CrossPlatformMachineEpsilon * 100)] + [InlineData( 8.8249778270762876, 3, 70.599822616610297, CrossPlatformMachineEpsilon * 100)] + [InlineData( double.PositiveInfinity, unchecked((int)(0x7FFFFFFF)), double.PositiveInfinity, 0)] + public static void ScaleB(double x, int n, double expectedResult, double allowedVariance) + { + AssertEqual(expectedResult, Math.ScaleB(x, n), allowedVariance); + } } }