From 715c71ae6af5775402e54d3b8ab6c4a888da3cb5 Mon Sep 17 00:00:00 2001 From: Tanner Gooding Date: Mon, 20 Jun 2022 16:14:52 -0700 Subject: [PATCH] Exposing IRootFunctions.Hypot and IRootFunctions.Root (#71010) * Exposing IRootFunctions.Hypot and IRootFunctions.Root * Adding tests for IRootFunctions.Hypot and IRootFunctions.Root --- THIRD-PARTY-NOTICES.TXT | 29 +- .../src/System/Double.cs | 290 ++++++++++++++- .../System.Private.CoreLib/src/System/Half.cs | 12 +- .../src/System/Numerics/IRootFunctions.cs | 16 +- .../System/Runtime/InteropServices/NFloat.cs | 12 +- .../src/System/Single.cs | 184 +++++++++- .../ref/System.Runtime.InteropServices.cs | 4 +- .../Runtime/InteropServices/NFloatTests.cs | 332 ++++++++++++++++++ .../System.Runtime/ref/System.Runtime.cs | 14 +- .../tests/System/DoubleTests.cs | 166 +++++++++ .../System.Runtime/tests/System/HalfTests.cs | 248 +++++++++++-- .../tests/System/SingleTests.cs | 166 +++++++++ 12 files changed, 1404 insertions(+), 69 deletions(-) diff --git a/THIRD-PARTY-NOTICES.TXT b/THIRD-PARTY-NOTICES.TXT index bfbc03e9c59..83f7a5ab45d 100644 --- a/THIRD-PARTY-NOTICES.TXT +++ b/THIRD-PARTY-NOTICES.TXT @@ -1108,4 +1108,31 @@ Copyright (C) 1999 Lucent Technologies Excerpted from 'The Practice of Programming by Brian W. Kernighan and Rob Pike -You may use this code for any purpose, as long as you leave the copyright notice and book citation attached. \ No newline at end of file +You may use this code for any purpose, as long as you leave the copyright notice and book citation attached. + +License notice for amd/aocl-libm-ose +------------------------------- + +Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: +1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +3. Neither the name of the copyright holder nor the names of its contributors + may be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/src/libraries/System.Private.CoreLib/src/System/Double.cs b/src/libraries/System.Private.CoreLib/src/System/Double.cs index aee762bb058..3ad8e88c640 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Double.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Double.cs @@ -12,6 +12,7 @@ ===========================================================*/ using System.Buffers.Binary; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Numerics; @@ -106,6 +107,9 @@ namespace System internal const ulong MinTrailingSignificand = 0x0000_0000_0000_0000; internal const ulong MaxTrailingSignificand = 0x000F_FFFF_FFFF_FFFF; + internal const int TrailingSignificandLength = 52; + internal const int SignificandLength = TrailingSignificandLength + 1; + internal ushort BiasedExponent { get @@ -917,7 +921,7 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinati public static double Clamp(double value, double min, double max) => Math.Clamp(value, min, max); /// - public static double CopySign(double x, double y) => Math.CopySign(x, y); + public static double CopySign(double value, double sign) => Math.CopySign(value, sign); /// public static double Max(double x, double y) => Math.Max(x, y); @@ -1353,15 +1357,289 @@ private static bool TryConvertTo(double value, [NotNullWhen(true)] out T /// public static double Cbrt(double x) => Math.Cbrt(x); - // /// - // public static double Hypot(double x, double y) => Math.Hypot(x, y); + /// + public static double Hypot(double x, double y) + { + // This code is based on `hypot` from amd/aocl-libm-ose + // Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + // + // Licensed under the BSD 3-Clause "New" or "Revised" License + // See THIRD-PARTY-NOTICES.TXT for the full license text + + double result; + + if (IsFinite(x) && IsFinite(y)) + { + double ax = Abs(x); + double ay = Abs(y); + + if (ax == 0.0f) + { + result = ay; + } + else if (ay == 0.0f) + { + result = ax; + } + else + { + ulong xBits = BitConverter.DoubleToUInt64Bits(ax); + ulong yBits = BitConverter.DoubleToUInt64Bits(ay); + + uint xExp = (uint)((xBits >> BiasedExponentShift) & ShiftedExponentMask); + uint yExp = (uint)((yBits >> BiasedExponentShift) & ShiftedExponentMask); + + int expDiff = (int)(xExp - yExp); + double expFix = 1.0; + + if ((expDiff <= (SignificandLength + 1)) && (expDiff >= (-SignificandLength - 1))) + { + if ((xExp > (ExponentBias + 500)) || (yExp > (ExponentBias + 500))) + { + // To prevent overflow, scale down by 2^+600 + expFix = 4.149515568880993E+180; + + xBits -= 0x2580000000000000; + yBits -= 0x2580000000000000; + } + else if ((xExp < (ExponentBias - 500)) || (yExp < (ExponentBias - 500))) + { + // To prevent underflow, scale up by 2^-600 + expFix = 2.409919865102884E-181; + + xBits += 0x2580000000000000; + yBits += 0x2580000000000000; + + // For subnormal values, do an additional fixing up changing the + // adjustment to scale up by 2^601 instead and then subtract a + // correction of 2^601 to account for the implicit bit. + + if (xExp == 0) // x is subnormal + { + xBits += 0x0010000000000000; + + ax = BitConverter.UInt64BitsToDouble(xBits); + ax -= 9.232978617785736E-128; + + xBits = BitConverter.DoubleToUInt64Bits(ax); + } + + if (yExp == 0) // y is subnormal + { + yBits += 0x0010000000000000; + + ay = BitConverter.UInt64BitsToDouble(yBits); + ay -= 9.232978617785736E-128; + + yBits = BitConverter.DoubleToUInt64Bits(ay); + } + } + + ax = BitConverter.UInt64BitsToDouble(xBits); + ay = BitConverter.UInt64BitsToDouble(yBits); + + if (ax < ay) + { + // Sort so ax is greater than ay + double tmp = ax; + + ax = ay; + ay = tmp; + + ulong tmpBits = xBits; + + xBits = yBits; + yBits = tmpBits; + } + + Debug.Assert(ax >= ay); + + // Split ax and ay into a head and tail portion + + double xHead = BitConverter.UInt64BitsToDouble(xBits & 0xFFFF_FFFF_F800_0000); + double yHead = BitConverter.UInt64BitsToDouble(yBits & 0xFFFF_FFFF_F800_0000); + + double xTail = ax - xHead; + double yTail = ay - yHead; + + // Compute (x * x) + (y * y) with extra precision + // + // This includes taking into account expFix which may + // cause an underflow or overflow, but if it does that + // will still be the correct result. + + double xx = ax * ax; + double yy = ay * ay; + + double rHead = xx + yy; + double rTail = (xx - rHead) + yy; + + rTail += (xHead * xHead) - xx; + rTail += 2 * xHead * xTail; + rTail += xTail * xTail; + + if (expDiff == 0) + { + // We only need to do extra accounting when ax and ay have equal exponents + + rTail += (yHead * yHead) - yy; + rTail += 2 * yHead * yTail; + rTail += yTail * yTail; + } + + result = Sqrt(rHead + rTail) * expFix; + } + else + { + // x or y is insignificant compared to the other + result = x + y; + } + } + } + else if (IsInfinity(x) || IsInfinity(y)) + { + // IEEE 754 requires that we return +Infinity + // even if one of the inputs is NaN + + result = PositiveInfinity; + } + else + { + // IEEE 754 requires that we return NaN + // if either input is NaN and neither is Infinity + + result = NaN; + } + + return result; + } + + /// + public static double Root(double x, int n) + { + double result; + + if (n > 0) + { + if (n == 2) + { + result = (x != 0.0) ? Sqrt(x) : 0.0; + } + else if (n == 3) + { + result = Cbrt(x); + } + else + { + result = PositiveN(x, n); + } + } + else if (n < 0) + { + result = NegativeN(x, n); + } + else + { + Debug.Assert(n == 0); + result = NaN; + } + + return result; + + static double PositiveN(double x, int n) + { + double result; + + if (IsFinite(x)) + { + if (x != 0) + { + if ((x > 0) || IsOddInteger(n)) + { + result = Pow(Abs(x), 1.0 / n); + result = CopySign(result, x); + } + else + { + result = NaN; + } + } + else if (IsEvenInteger(n)) + { + result = 0.0; + } + else + { + result = CopySign(0.0, x); + } + } + else if (IsNaN(x)) + { + result = NaN; + } + else if (x > 0) + { + Debug.Assert(IsPositiveInfinity(x)); + result = PositiveInfinity; + } + else + { + Debug.Assert(IsNegativeInfinity(x)); + result = int.IsOddInteger(n) ? NegativeInfinity : NaN; + } + + return result; + } + + static double NegativeN(double x, int n) + { + double result; + + if (IsFinite(x)) + { + if (x != 0) + { + if ((x > 0) || IsOddInteger(n)) + { + result = Pow(Abs(x), 1.0 / n); + result = CopySign(result, x); + } + else + { + result = NaN; + } + } + else if (IsEvenInteger(n)) + { + result = PositiveInfinity; + } + else + { + result = CopySign(PositiveInfinity, x); + } + } + else if (IsNaN(x)) + { + result = NaN; + } + else if (x > 0) + { + Debug.Assert(IsPositiveInfinity(x)); + result = 0.0; + } + else + { + Debug.Assert(IsNegativeInfinity(x)); + result = int.IsOddInteger(n) ? -0.0 : NaN; + } + + return result; + } + } /// public static double Sqrt(double x) => Math.Sqrt(x); - // /// - // public static double Root(double x, double n) => Math.Root(x, n); - // // ISignedNumber // diff --git a/src/libraries/System.Private.CoreLib/src/System/Half.cs b/src/libraries/System.Private.CoreLib/src/System/Half.cs index 7e18eac88f4..2dde194b916 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Half.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Half.cs @@ -1359,7 +1359,7 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destination public static Half Clamp(Half value, Half min, Half max) => (Half)Math.Clamp((float)value, (float)min, (float)max); /// - public static Half CopySign(Half x, Half y) => (Half)MathF.CopySign((float)x, (float)y); + public static Half CopySign(Half value, Half sign) => (Half)MathF.CopySign((float)value, (float)sign); /// public static Half Max(Half x, Half y) => (Half)MathF.Max((float)x, (float)y); @@ -1788,15 +1788,15 @@ private static bool TryConvertTo(Half value, [NotNullWhen(true)] out TOt /// public static Half Cbrt(Half x) => (Half)MathF.Cbrt((float)x); - // /// - // public static Half Hypot(Half x, Half y) => (Half)MathF.Hypot((float)x, (float)y); + /// + public static Half Hypot(Half x, Half y) => (Half)float.Hypot((float)x, (float)y); + + /// + public static Half Root(Half x, int n) => (Half)float.Root((float)x, n); /// public static Half Sqrt(Half x) => (Half)MathF.Sqrt((float)x); - // /// - // public static Half Root(Half x, Half n) => (Half)MathF.Root((float)x, (float)n); - // // ISignedNumber // diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IRootFunctions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IRootFunctions.cs index f4215cdd72c..b7ba1d5bd2a 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IRootFunctions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IRootFunctions.cs @@ -13,13 +13,21 @@ public interface IRootFunctions /// The cube-root of . static abstract TSelf Cbrt(TSelf x); + /// Computes the hypotenuse given two values representing the lengths of the shorter sides in a right-angled triangle. + /// The value to square and add to . + /// The value to square and add to . + /// The square root of -squared plus -squared. + static abstract TSelf Hypot(TSelf x, TSelf y); + + /// Computes the n-th root of a value. + /// The value whose -th root is to be computed. + /// The degree of the root to be computed. + /// The -th root of . + static abstract TSelf Root(TSelf x, int n); + /// Computes the square-root of a value. /// The value whose square-root is to be computed. /// The square-root of . static abstract TSelf Sqrt(TSelf x); - - // The following methods are approved but not yet implemented in the libraries - // * static abstract TSelf Hypot(TSelf x, TSelf y); - // * static abstract TSelf Root(TSelf x, TSelf n); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs index 1366ebf68c2..b3f4213a29b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs @@ -1213,7 +1213,7 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinati public static NFloat Clamp(NFloat value, NFloat min, NFloat max) => new NFloat(NativeType.Clamp(value._value, min._value, max._value)); /// - public static NFloat CopySign(NFloat x, NFloat y) => new NFloat(NativeType.CopySign(x._value, y._value)); + public static NFloat CopySign(NFloat value, NFloat sign) => new NFloat(NativeType.CopySign(value._value, sign._value)); /// public static NFloat Max(NFloat x, NFloat y) => new NFloat(NativeType.Max(x._value, y._value)); @@ -1700,15 +1700,15 @@ private static bool TryConvertTo(NFloat value, [NotNullWhen(true)] out T /// public static NFloat Cbrt(NFloat x) => new NFloat(NativeType.Cbrt(x._value)); - // /// - // public static NFloat Hypot(NFloat x, NFloat y) => new NFloat(NativeType.Hypot(x._value, y._value)); + /// + public static NFloat Hypot(NFloat x, NFloat y) => new NFloat(NativeType.Hypot(x._value, y._value)); + + /// + public static NFloat Root(NFloat x, int n) => new NFloat(NativeType.Root(x._value, n)); /// public static NFloat Sqrt(NFloat x) => new NFloat(NativeType.Sqrt(x._value)); - // /// - // public static NFloat Root(NFloat x, NFloat n) => new NFloat(NativeType.Root(x._value, n._value)); - // // ISignedNumber // diff --git a/src/libraries/System.Private.CoreLib/src/System/Single.cs b/src/libraries/System.Private.CoreLib/src/System/Single.cs index 9a9b32d1d6c..2d45346b5c9 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Single.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Single.cs @@ -11,6 +11,7 @@ ===========================================================*/ using System.Buffers.Binary; +using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Numerics; @@ -900,7 +901,7 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinatio public static float Clamp(float value, float min, float max) => Math.Clamp(value, min, max); /// - public static float CopySign(float x, float y) => MathF.CopySign(x, y); + public static float CopySign(float value, float sign) => MathF.CopySign(value, sign); /// public static float Max(float x, float y) => MathF.Max(x, y); @@ -1336,15 +1337,186 @@ private static bool TryConvertTo(float value, [NotNullWhen(true)] out TO /// public static float Cbrt(float x) => MathF.Cbrt(x); - // /// - // public static float Hypot(float x, float y) => MathF.Hypot(x, y); + /// + public static float Hypot(float x, float y) + { + // This code is based on `hypotf` from amd/aocl-libm-ose + // Copyright (C) 2008-2020 Advanced Micro Devices, Inc. All rights reserved. + // + // Licensed under the BSD 3-Clause "New" or "Revised" License + // See THIRD-PARTY-NOTICES.TXT for the full license text + + float result; + + if (IsFinite(x) && IsFinite(y)) + { + float ax = Abs(x); + float ay = Abs(y); + + if (ax == 0.0f) + { + result = ay; + } + else if (ay == 0.0f) + { + result = ax; + } + else + { + double xx = ax; + xx *= xx; + + double yy = ay; + yy *= yy; + + result = (float)double.Sqrt(xx + yy); + } + } + else if (IsInfinity(x) || IsInfinity(y)) + { + // IEEE 754 requires that we return +Infinity + // even if one of the inputs is NaN + + result = PositiveInfinity; + } + else + { + // IEEE 754 requires that we return NaN + // if either input is NaN and neither is Infinity + + Debug.Assert(IsNaN(x) || IsNaN(y)); + result = NaN; + } + + return result; + } + + /// + public static float Root(float x, int n) + { + float result; + + if (n > 0) + { + if (n == 2) + { + result = (x != 0.0f) ? Sqrt(x) : 0.0f; + } + else if (n == 3) + { + result = Cbrt(x); + } + else + { + result = PositiveN(x, n); + } + } + else if (n < 0) + { + result = NegativeN(x, n); + } + else + { + Debug.Assert(n == 0); + result = NaN; + } + + return result; + + static float PositiveN(float x, int n) + { + float result; + + if (IsFinite(x)) + { + if (x != 0) + { + if ((x > 0) || IsOddInteger(n)) + { + result = (float)double.Pow(Abs(x), 1.0 / n); + result = CopySign(result, x); + } + else + { + result = NaN; + } + } + else if (IsEvenInteger(n)) + { + result = 0.0f; + } + else + { + result = CopySign(0.0f, x); + } + } + else if (IsNaN(x)) + { + result = NaN; + } + else if (x > 0) + { + Debug.Assert(IsPositiveInfinity(x)); + result = PositiveInfinity; + } + else + { + Debug.Assert(IsNegativeInfinity(x)); + result = int.IsOddInteger(n) ? NegativeInfinity : NaN; + } + + return result; + } + + static float NegativeN(float x, int n) + { + float result; + + if (IsFinite(x)) + { + if (x != 0) + { + if ((x > 0) || IsOddInteger(n)) + { + result = (float)double.Pow(Abs(x), 1.0 / n); + result = CopySign(result, x); + } + else + { + result = NaN; + } + } + else if (IsEvenInteger(n)) + { + result = PositiveInfinity; + } + else + { + result = CopySign(PositiveInfinity, x); + } + } + else if (IsNaN(x)) + { + result = NaN; + } + else if (x > 0) + { + Debug.Assert(IsPositiveInfinity(x)); + result = 0.0f; + } + else + { + Debug.Assert(IsNegativeInfinity(x)); + result = int.IsOddInteger(n) ? -0.0f : NaN; + } + + return result; + } + } /// public static float Sqrt(float x) => MathF.Sqrt(x); - // /// - // public static float Root(float x, float n) => MathF.Root(x, n); - // // ISignedNumber // diff --git a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs index fe4bcd09205..75eca17032a 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -850,7 +850,7 @@ public static unsafe partial class NativeMemory public static System.Runtime.InteropServices.NFloat Clamp(System.Runtime.InteropServices.NFloat value, System.Runtime.InteropServices.NFloat min, System.Runtime.InteropServices.NFloat max) { throw null; } public int CompareTo(object? obj) { throw null; } public int CompareTo(System.Runtime.InteropServices.NFloat other) { throw null; } - public static System.Runtime.InteropServices.NFloat CopySign(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } + public static System.Runtime.InteropServices.NFloat CopySign(System.Runtime.InteropServices.NFloat value, System.Runtime.InteropServices.NFloat sign) { throw null; } public static System.Runtime.InteropServices.NFloat Cos(System.Runtime.InteropServices.NFloat x) { throw null; } public static System.Runtime.InteropServices.NFloat Cosh(System.Runtime.InteropServices.NFloat x) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } @@ -864,6 +864,7 @@ public static unsafe partial class NativeMemory public static System.Runtime.InteropServices.NFloat Floor(System.Runtime.InteropServices.NFloat x) { throw null; } public static System.Runtime.InteropServices.NFloat FusedMultiplyAdd(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right, System.Runtime.InteropServices.NFloat addend) { throw null; } public override int GetHashCode() { throw null; } + public static System.Runtime.InteropServices.NFloat Hypot(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat Ieee754Remainder(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right) { throw null; } public static int ILogB(System.Runtime.InteropServices.NFloat x) { throw null; } public static bool IsEvenInteger(System.Runtime.InteropServices.NFloat value) { throw null; } @@ -984,6 +985,7 @@ public static unsafe partial class NativeMemory public static System.Runtime.InteropServices.NFloat Pow(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat ReciprocalEstimate(System.Runtime.InteropServices.NFloat x) { throw null; } public static System.Runtime.InteropServices.NFloat ReciprocalSqrtEstimate(System.Runtime.InteropServices.NFloat x) { throw null; } + public static System.Runtime.InteropServices.NFloat Root(System.Runtime.InteropServices.NFloat x, int n) { throw null; } public static System.Runtime.InteropServices.NFloat Round(System.Runtime.InteropServices.NFloat x) { throw null; } public static System.Runtime.InteropServices.NFloat Round(System.Runtime.InteropServices.NFloat x, int digits) { throw null; } public static System.Runtime.InteropServices.NFloat Round(System.Runtime.InteropServices.NFloat x, int digits, System.MidpointRounding mode) { throw null; } diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/NFloatTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/NFloatTests.cs index cd3a5d1b248..fb12b52eebb 100644 --- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/NFloatTests.cs +++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/NFloatTests.cs @@ -1440,6 +1440,172 @@ public static void Log10P1Test32(float value, float expectedResult, float allowe AssertExtensions.Equal(expectedResult, (float)NFloat.Log10P1(value), allowedVariance); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))] + [InlineData(float.NaN, float.NaN, float.NaN, 0.0f)] + [InlineData(float.NaN, 0.0f, float.NaN, 0.0f)] + [InlineData(float.NaN, 1.0f, float.NaN, 0.0f)] + [InlineData(float.NaN, 2.71828183f, float.NaN, 0.0f)] + [InlineData(float.NaN, 10.0f, float.NaN, 0.0f)] + [InlineData(0.0f, 0.0f, 0.0f, 0.0f)] + [InlineData(0.0f, 1.0f, 1.0f, 0.0f)] + [InlineData(0.0f, 1.57079633f, 1.57079633f, 0.0f)] + [InlineData(0.0f, 2.0f, 2.0f, 0.0f)] + [InlineData(0.0f, 2.71828183f, 2.71828183f, 0.0f)] + [InlineData(0.0f, 3.0f, 3.0f, 0.0f)] + [InlineData(0.0f, 10.0f, 10.0f, 0.0f)] + [InlineData(1.0f, 1.0f, 1.41421356f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData(2.71828183f, 0.318309886f, 2.73685536f, CrossPlatformMachineEpsilon32 * 10)] // x: (e) y: (1 / pi) + [InlineData(2.71828183f, 0.434294482f, 2.75275640f, CrossPlatformMachineEpsilon32 * 10)] // x: (e) y: (log10(e)) + [InlineData(2.71828183f, 0.636619772f, 2.79183467f, CrossPlatformMachineEpsilon32 * 10)] // x: (e) y: (2 / pi) + [InlineData(2.71828183f, 0.693147181f, 2.80526454f, CrossPlatformMachineEpsilon32 * 10)] // x: (e) y: (ln(2)) + [InlineData(2.71828183f, 0.707106781f, 2.80874636f, CrossPlatformMachineEpsilon32 * 10)] // x: (e) y: (1 / sqrt(2)) + [InlineData(2.71828183f, 0.785398163f, 2.82947104f, CrossPlatformMachineEpsilon32 * 10)] // x: (e) y: (pi / 4) + [InlineData(2.71828183f, 1.0f, 2.89638673f, CrossPlatformMachineEpsilon32 * 10)] // x: (e) + [InlineData(2.71828183f, 1.12837917f, 2.94317781f, CrossPlatformMachineEpsilon32 * 10)] // x: (e) y: (2 / sqrt(pi)) + [InlineData(2.71828183f, 1.41421356f, 3.06415667f, CrossPlatformMachineEpsilon32 * 10)] // x: (e) y: (sqrt(2)) + [InlineData(2.71828183f, 1.44269504f, 3.07740558f, CrossPlatformMachineEpsilon32 * 10)] // x: (e) y: (log2(e)) + [InlineData(2.71828183f, 1.57079633f, 3.13949951f, CrossPlatformMachineEpsilon32 * 10)] // x: (e) y: (pi / 2) + [InlineData(2.71828183f, 2.30258509f, 3.56243656f, CrossPlatformMachineEpsilon32 * 10)] // x: (e) y: (ln(10)) + [InlineData(2.71828183f, 2.71828183f, 3.84423103f, CrossPlatformMachineEpsilon32 * 10)] // x: (e) y: (e) + [InlineData(2.71828183f, 3.14159265f, 4.15435440f, CrossPlatformMachineEpsilon32 * 10)] // x: (e) y: (pi) + [InlineData(10.0f, 0.318309886f, 10.0050648f, CrossPlatformMachineEpsilon32 * 100)] // y: (1 / pi) + [InlineData(10.0f, 0.434294482f, 10.0094261f, CrossPlatformMachineEpsilon32 * 100)] // y: (log10(e)) + [InlineData(10.0f, 0.636619772f, 10.0202437f, CrossPlatformMachineEpsilon32 * 100)] // y: (2 / pi) + [InlineData(10.0f, 0.693147181f, 10.0239939f, CrossPlatformMachineEpsilon32 * 100)] // y: (ln(2)) + [InlineData(10.0f, 0.707106781f, 10.0249688f, CrossPlatformMachineEpsilon32 * 100)] // y: (1 / sqrt(2)) + [InlineData(10.0f, 0.785398163f, 10.0307951f, CrossPlatformMachineEpsilon32 * 100)] // y: (pi / 4) + [InlineData(10.0f, 1.0f, 10.0498756f, CrossPlatformMachineEpsilon32 * 100)] // + [InlineData(10.0f, 1.12837917f, 10.0634606f, CrossPlatformMachineEpsilon32 * 100)] // y: (2 / sqrt(pi)) + [InlineData(10.0f, 1.41421356f, 10.0995049f, CrossPlatformMachineEpsilon32 * 100)] // y: (sqrt(2)) + [InlineData(10.0f, 1.44269504f, 10.1035325f, CrossPlatformMachineEpsilon32 * 100)] // y: (log2(e)) + [InlineData(10.0f, 1.57079633f, 10.1226183f, CrossPlatformMachineEpsilon32 * 100)] // y: (pi / 2) + [InlineData(10.0f, 2.30258509f, 10.2616713f, CrossPlatformMachineEpsilon32 * 100)] // y: (ln(10)) + [InlineData(10.0f, 2.71828183f, 10.3628691f, CrossPlatformMachineEpsilon32 * 100)] // y: (e) + [InlineData(10.0f, 3.14159265f, 10.4818703f, CrossPlatformMachineEpsilon32 * 100)] // y: (pi) + [InlineData(float.PositiveInfinity, float.NaN, float.PositiveInfinity, 0.0f)] + [InlineData(float.PositiveInfinity, 0.0f, float.PositiveInfinity, 0.0f)] + [InlineData(float.PositiveInfinity, 1.0f, float.PositiveInfinity, 0.0f)] + [InlineData(float.PositiveInfinity, 2.71828183f, float.PositiveInfinity, 0.0f)] + [InlineData(float.PositiveInfinity, 10.0f, float.PositiveInfinity, 0.0f)] + [InlineData(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Hypot32(float x, float y, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, NFloat.Hypot(-x, -y), allowedVariance); + AssertExtensions.Equal(expectedResult, NFloat.Hypot(-x, +y), allowedVariance); + AssertExtensions.Equal(expectedResult, NFloat.Hypot(+x, -y), allowedVariance); + AssertExtensions.Equal(expectedResult, NFloat.Hypot(+x, +y), allowedVariance); + + AssertExtensions.Equal(expectedResult, NFloat.Hypot(-y, -x), allowedVariance); + AssertExtensions.Equal(expectedResult, NFloat.Hypot(-y, +x), allowedVariance); + AssertExtensions.Equal(expectedResult, NFloat.Hypot(+y, -x), allowedVariance); + AssertExtensions.Equal(expectedResult, NFloat.Hypot(+y, +x), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))] + [InlineData( float.NegativeInfinity, -5, -0.0f, 0.0f)] + [InlineData( float.NegativeInfinity, -4, float.NaN, 0.0f)] + [InlineData( float.NegativeInfinity, -3, -0.0f, 0.0f)] + [InlineData( float.NegativeInfinity, -2, float.NaN, 0.0f)] + [InlineData( float.NegativeInfinity, -1, -0.0f, 0.0f)] + [InlineData( float.NegativeInfinity, 0, float.NaN, 0.0f)] + [InlineData( float.NegativeInfinity, 1, float.NegativeInfinity, 0.0f)] + [InlineData( float.NegativeInfinity, 2, float.NaN, 0.0f)] + [InlineData( float.NegativeInfinity, 3, float.NegativeInfinity, 0.0f)] + [InlineData( float.NegativeInfinity, 4, float.NaN, 0.0f)] + [InlineData( float.NegativeInfinity, 5, float.NegativeInfinity, 0.0f)] + [InlineData(-2.71828183f, -5, -0.81873075f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData(-2.71828183f, -4, float.NaN, 0.0f)] + [InlineData(-2.71828183f, -3, -0.71653131f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData(-2.71828183f, -2, float.NaN, 0.0f)] + [InlineData(-2.71828183f, -1, -0.36787944f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData(-2.71828183f, 0, float.NaN, 0.0f)] + [InlineData(-2.71828183f, 1, -2.71828183f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData(-2.71828183f, 2, float.NaN, 0.0f)] + [InlineData(-2.71828183f, 3, -1.39561243f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData(-2.71828183f, 4, float.NaN, 0.0f)] + [InlineData(-2.71828183f, 5, -1.22140276f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData(-1.0f, -5, -1.0f, 0.0f)] + [InlineData(-1.0f, -4, float.NaN, 0.0f)] + [InlineData(-1.0f, -3, -1.0f, 0.0f)] + [InlineData(-1.0f, -2, float.NaN, 0.0f)] + [InlineData(-1.0f, -1, -1.0f, 0.0f)] + [InlineData(-1.0f, 0, float.NaN, 0.0f)] + [InlineData(-1.0f, 1, -1.0f, 0.0f)] + [InlineData(-1.0f, 2, float.NaN, 0.0f)] + [InlineData(-1.0f, 3, -1.0f, 0.0f)] + [InlineData(-1.0f, 4, float.NaN, 0.0f)] + [InlineData(-1.0f, 5, -1.0f, 0.0f)] + [InlineData(-0.0f, -5, float.NegativeInfinity, 0.0f)] + [InlineData(-0.0f, -4, float.PositiveInfinity, 0.0f)] + [InlineData(-0.0f, -3, float.NegativeInfinity, 0.0f)] + [InlineData(-0.0f, -2, float.PositiveInfinity, 0.0f)] + [InlineData(-0.0f, -1, float.NegativeInfinity, 0.0f)] + [InlineData(-0.0f, 0, float.NaN, 0.0f)] + [InlineData(-0.0f, 1, -0.0f, 0.0f)] + [InlineData(-0.0f, 2, 0.0f, 0.0f)] + [InlineData(-0.0f, 3, -0.0f, 0.0f)] + [InlineData(-0.0f, 4, 0.0f, 0.0f)] + [InlineData(-0.0f, 5, -0.0f, 0.0f)] + [InlineData( float.NaN, -5, float.NaN, 0.0f)] + [InlineData( float.NaN, -4, float.NaN, 0.0f)] + [InlineData( float.NaN, -3, float.NaN, 0.0f)] + [InlineData( float.NaN, -2, float.NaN, 0.0f)] + [InlineData( float.NaN, -1, float.NaN, 0.0f)] + [InlineData( float.NaN, 0, float.NaN, 0.0f)] + [InlineData( float.NaN, 1, float.NaN, 0.0f)] + [InlineData( float.NaN, 2, float.NaN, 0.0f)] + [InlineData( float.NaN, 3, float.NaN, 0.0f)] + [InlineData( float.NaN, 4, float.NaN, 0.0f)] + [InlineData( float.NaN, 5, float.NaN, 0.0f)] + [InlineData( 0.0f, -5, float.PositiveInfinity, 0.0f)] + [InlineData( 0.0f, -4, float.PositiveInfinity, 0.0f)] + [InlineData( 0.0f, -3, float.PositiveInfinity, 0.0f)] + [InlineData( 0.0f, -2, float.PositiveInfinity, 0.0f)] + [InlineData( 0.0f, -1, float.PositiveInfinity, 0.0f)] + [InlineData( 0.0f, 0, float.NaN, 0.0f)] + [InlineData( 0.0f, 1, 0.0f, 0.0f)] + [InlineData( 0.0f, 2, 0.0f, 0.0f)] + [InlineData( 0.0f, 3, 0.0f, 0.0f)] + [InlineData( 0.0f, 4, 0.0f, 0.0f)] + [InlineData( 0.0f, 5, 0.0f, 0.0f)] + [InlineData( 1.0f, -5, 1.0f, 0.0f)] + [InlineData( 1.0f, -4, 1.0f, 0.0f)] + [InlineData( 1.0f, -3, 1.0f, 0.0f)] + [InlineData( 1.0f, -2, 1.0f, 0.0f)] + [InlineData( 1.0f, -1, 1.0f, 0.0f)] + [InlineData( 1.0f, 0, float.NaN, 0.0f)] + [InlineData( 1.0f, 1, 1.0f, 0.0f)] + [InlineData( 1.0f, 2, 1.0f, 0.0f)] + [InlineData( 1.0f, 3, 1.0f, 0.0f)] + [InlineData( 1.0f, 4, 1.0f, 0.0f)] + [InlineData( 1.0f, 5, 1.0f, 0.0f)] + [InlineData( 2.71828183f, -5, 0.81873075f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 2.71828183f, -4, 0.77880078f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 2.71828183f, -3, 0.71653131f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 2.71828183f, -2, 0.60653066f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 2.71828183f, -1, 0.36787944f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 2.71828183f, 0, float.NaN, 0.0f)] + [InlineData( 2.71828183f, 1, 2.71828183f, 0.0f)] + [InlineData( 2.71828183f, 2, 1.64872127f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 2.71828183f, 3, 1.39561243f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 2.71828183f, 4, 1.28402542f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 2.71828183f, 5, 1.22140276f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( float.PositiveInfinity, -5, 0.0f, 0.0f)] + [InlineData( float.PositiveInfinity, -4, 0.0f, 0.0f)] + [InlineData( float.PositiveInfinity, -3, 0.0f, 0.0f)] + [InlineData( float.PositiveInfinity, -2, 0.0f, 0.0f)] + [InlineData( float.PositiveInfinity, -1, 0.0f, 0.0f)] + [InlineData( float.PositiveInfinity, 0, float.NaN, 0.0f)] + [InlineData( float.PositiveInfinity, 1, float.PositiveInfinity, 0.0f)] + [InlineData( float.PositiveInfinity, 2, float.PositiveInfinity, 0.0f)] + [InlineData( float.PositiveInfinity, 3, float.PositiveInfinity, 0.0f)] + [InlineData( float.PositiveInfinity, 4, float.PositiveInfinity, 0.0f)] + [InlineData( float.PositiveInfinity, 5, float.PositiveInfinity, 0.0f)] + public static void Root32(float x, int n, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, NFloat.Root(x, n), allowedVariance); + } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] [InlineData( double.NegativeInfinity, -1.0, 0.0)] [InlineData(-3.1415926535897932, -0.95678608173622775, CrossPlatformMachineEpsilon64)] // value: -(pi) @@ -1757,5 +1923,171 @@ public static void Log10P1Test64(double value, double expectedResult, double all { AssertExtensions.Equal(expectedResult, NFloat.Log10P1((NFloat)value), allowedVariance); } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] + [InlineData(double.NaN, double.NaN, double.NaN, 0.0)] + [InlineData(double.NaN, 0.0f, double.NaN, 0.0)] + [InlineData(double.NaN, 1.0f, double.NaN, 0.0)] + [InlineData(double.NaN, 2.7182818284590452, double.NaN, 0.0)] + [InlineData(double.NaN, 10.0, double.NaN, 0.0)] + [InlineData(0.0, 0.0, 0.0, 0.0)] + [InlineData(0.0, 1.0, 1.0, 0.0)] + [InlineData(0.0, 1.5707963267948966, 1.5707963267948966, 0.0)] + [InlineData(0.0, 2.0, 2.0, 0.0)] + [InlineData(0.0, 2.7182818284590452, 2.7182818284590452, 0.0)] + [InlineData(0.0, 3.0, 3.0, 0.0)] + [InlineData(0.0, 10.0, 10.0, 0.0)] + [InlineData(1.0, 1.0, 1.4142135623730950, CrossPlatformMachineEpsilon64 * 10)] + [InlineData(2.7182818284590452, 0.31830988618379067, 2.7368553638387594, CrossPlatformMachineEpsilon64 * 10)] // x: (e) y: (1 / pi) + [InlineData(2.7182818284590452, 0.43429448190325183, 2.7527563996732919, CrossPlatformMachineEpsilon64 * 10)] // x: (e) y: (log10(e)) + [InlineData(2.7182818284590452, 0.63661977236758134, 2.7918346715914253, CrossPlatformMachineEpsilon64 * 10)] // x: (e) y: (2 / pi) + [InlineData(2.7182818284590452, 0.69314718055994531, 2.8052645352709344, CrossPlatformMachineEpsilon64 * 10)] // x: (e) y: (ln(2)) + [InlineData(2.7182818284590452, 0.70710678118654752, 2.8087463571726533, CrossPlatformMachineEpsilon64 * 10)] // x: (e) y: (1 / sqrt(2)) + [InlineData(2.7182818284590452, 0.78539816339744831, 2.8294710413783590, CrossPlatformMachineEpsilon64 * 10)] // x: (e) y: (pi / 4) + [InlineData(2.7182818284590452, 1.0, 2.8963867315900082, CrossPlatformMachineEpsilon64 * 10)] // x: (e) + [InlineData(2.7182818284590452, 1.1283791670955126, 2.9431778138036127, CrossPlatformMachineEpsilon64 * 10)] // x: (e) y: (2 / sqrt(pi)) + [InlineData(2.7182818284590452, 1.4142135623730950, 3.0641566701020120, CrossPlatformMachineEpsilon64 * 10)] // x: (e) y: (sqrt(2)) + [InlineData(2.7182818284590452, 1.4426950408889634, 3.0774055761202907, CrossPlatformMachineEpsilon64 * 10)] // x: (e) y: (log2(e)) + [InlineData(2.7182818284590452, 1.5707963267948966, 3.1394995141268918, CrossPlatformMachineEpsilon64 * 10)] // x: (e) y: (pi / 2) + [InlineData(2.7182818284590452, 2.3025850929940457, 3.5624365551415857, CrossPlatformMachineEpsilon64 * 10)] // x: (e) y: (ln(10)) + [InlineData(2.7182818284590452, 2.7182818284590452, 3.8442310281591168, CrossPlatformMachineEpsilon64 * 10)] // x: (e) y: (e) + [InlineData(2.7182818284590452, 3.1415926535897932, 4.1543544023133136, CrossPlatformMachineEpsilon64 * 10)] // x: (e) y: (pi) + [InlineData(10.0, 0.31830988618379067, 10.005064776584025, CrossPlatformMachineEpsilon64 * 100)] // y: (1 / pi) + [InlineData(10.0, 0.43429448190325183, 10.009426142242702, CrossPlatformMachineEpsilon64 * 100)] // y: (log10(e)) + [InlineData(10.0, 0.63661977236758134, 10.020243746265325, CrossPlatformMachineEpsilon64 * 100)] // y: (2 / pi) + [InlineData(10.0, 0.69314718055994531, 10.023993865417028, CrossPlatformMachineEpsilon64 * 100)] // y: (ln(2)) + [InlineData(10.0, 0.70710678118654752, 10.024968827881711, CrossPlatformMachineEpsilon64 * 100)] // y: (1 / sqrt(2)) + [InlineData(10.0, 0.78539816339744831, 10.030795096853892, CrossPlatformMachineEpsilon64 * 100)] // y: (pi / 4) + [InlineData(10.0, 1.0, 10.049875621120890, CrossPlatformMachineEpsilon64 * 100)] // + [InlineData(10.0, 1.1283791670955126, 10.063460614755501, CrossPlatformMachineEpsilon64 * 100)] // y: (2 / sqrt(pi)) + [InlineData(10.0, 1.4142135623730950, 10.099504938362078, CrossPlatformMachineEpsilon64 * 100)] // y: (sqrt(2)) + [InlineData(10.0, 1.4426950408889634, 10.103532500121213, CrossPlatformMachineEpsilon64 * 100)] // y: (log2(e)) + [InlineData(10.0, 1.5707963267948966, 10.122618292728040, CrossPlatformMachineEpsilon64 * 100)] // y: (pi / 2) + [InlineData(10.0, 2.3025850929940457, 10.261671311754163, CrossPlatformMachineEpsilon64 * 100)] // y: (ln(10)) + [InlineData(10.0, 2.7182818284590452, 10.362869105558106, CrossPlatformMachineEpsilon64 * 100)] // y: (e) + [InlineData(10.0, 3.1415926535897932, 10.481870272097884, CrossPlatformMachineEpsilon64 * 100)] // y: (pi) + [InlineData(double.PositiveInfinity, double.NaN, double.PositiveInfinity, 0.0)] + [InlineData(double.PositiveInfinity, 0.0, double.PositiveInfinity, 0.0)] + [InlineData(double.PositiveInfinity, 1.0, double.PositiveInfinity, 0.0)] + [InlineData(double.PositiveInfinity, 2.7182818284590452, double.PositiveInfinity, 0.0)] + [InlineData(double.PositiveInfinity, 10.0, double.PositiveInfinity, 0.0)] + [InlineData(double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Hypot64(double x, double y, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, NFloat.Hypot((NFloat)(-x), (NFloat)(-y)), allowedVariance); + AssertExtensions.Equal(expectedResult, NFloat.Hypot((NFloat)(-x), (NFloat)(+y)), allowedVariance); + AssertExtensions.Equal(expectedResult, NFloat.Hypot((NFloat)(+x), (NFloat)(-y)), allowedVariance); + AssertExtensions.Equal(expectedResult, NFloat.Hypot((NFloat)(+x), (NFloat)(+y)), allowedVariance); + + AssertExtensions.Equal(expectedResult, NFloat.Hypot((NFloat)(-y), (NFloat)(-x)), allowedVariance); + AssertExtensions.Equal(expectedResult, NFloat.Hypot((NFloat)(-y), (NFloat)(+x)), allowedVariance); + AssertExtensions.Equal(expectedResult, NFloat.Hypot((NFloat)(+y), (NFloat)(-x)), allowedVariance); + AssertExtensions.Equal(expectedResult, NFloat.Hypot((NFloat)(+y), (NFloat)(+x)), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] + [InlineData( double.NegativeInfinity, -5, -0.0, 0.0)] + [InlineData( double.NegativeInfinity, -4, double.NaN, 0.0)] + [InlineData( double.NegativeInfinity, -3, -0.0, 0.0)] + [InlineData( double.NegativeInfinity, -2, double.NaN, 0.0)] + [InlineData( double.NegativeInfinity, -1, -0.0, 0.0)] + [InlineData( double.NegativeInfinity, 0, double.NaN, 0.0)] + [InlineData( double.NegativeInfinity, 1, double.NegativeInfinity, 0.0)] + [InlineData( double.NegativeInfinity, 2, double.NaN, 0.0)] + [InlineData( double.NegativeInfinity, 3, double.NegativeInfinity, 0.0)] + [InlineData( double.NegativeInfinity, 4, double.NaN, 0.0)] + [InlineData( double.NegativeInfinity, 5, double.NegativeInfinity, 0.0)] + [InlineData(-2.7182818284590452, -5, -0.8187307530779819, CrossPlatformMachineEpsilon64 * 10)] + [InlineData(-2.7182818284590452, -4, double.NaN, 0.0)] + [InlineData(-2.7182818284590452, -3, -0.7165313105737893, CrossPlatformMachineEpsilon64 * 10)] + [InlineData(-2.7182818284590452, -2, double.NaN, 0.0)] + [InlineData(-2.7182818284590452, -1, -0.3678794411714423, CrossPlatformMachineEpsilon64 * 10)] + [InlineData(-2.7182818284590452, 0, double.NaN, 0.0)] + [InlineData(-2.7182818284590452, 1, -2.7182818284590452, CrossPlatformMachineEpsilon64 * 10)] + [InlineData(-2.7182818284590452, 2, double.NaN, 0.0)] + [InlineData(-2.7182818284590452, 3, -1.3956124250860895, CrossPlatformMachineEpsilon64 * 10)] + [InlineData(-2.7182818284590452, 4, double.NaN, 0.0)] + [InlineData(-2.7182818284590452, 5, -1.2214027581601698, CrossPlatformMachineEpsilon64 * 10)] + [InlineData(-1.0, -5, -1.0, 0.0)] + [InlineData(-1.0, -4, double.NaN, 0.0)] + [InlineData(-1.0, -3, -1.0, 0.0)] + [InlineData(-1.0, -2, double.NaN, 0.0)] + [InlineData(-1.0, -1, -1.0, 0.0)] + [InlineData(-1.0, 0, double.NaN, 0.0)] + [InlineData(-1.0, 1, -1.0, 0.0)] + [InlineData(-1.0, 2, double.NaN, 0.0)] + [InlineData(-1.0, 3, -1.0, 0.0)] + [InlineData(-1.0, 4, double.NaN, 0.0)] + [InlineData(-1.0, 5, -1.0, 0.0)] + [InlineData(-0.0, -5, double.NegativeInfinity, 0.0)] + [InlineData(-0.0, -4, double.PositiveInfinity, 0.0)] + [InlineData(-0.0, -3, double.NegativeInfinity, 0.0)] + [InlineData(-0.0, -2, double.PositiveInfinity, 0.0)] + [InlineData(-0.0, -1, double.NegativeInfinity, 0.0)] + [InlineData(-0.0, 0, double.NaN, 0.0)] + [InlineData(-0.0, 1, -0.0, 0.0)] + [InlineData(-0.0, 2, 0.0, 0.0)] + [InlineData(-0.0, 3, -0.0, 0.0)] + [InlineData(-0.0, 4, 0.0, 0.0)] + [InlineData(-0.0, 5, -0.0, 0.0)] + [InlineData( double.NaN, -5, double.NaN, 0.0)] + [InlineData( double.NaN, -4, double.NaN, 0.0)] + [InlineData( double.NaN, -3, double.NaN, 0.0)] + [InlineData( double.NaN, -2, double.NaN, 0.0)] + [InlineData( double.NaN, -1, double.NaN, 0.0)] + [InlineData( double.NaN, 0, double.NaN, 0.0)] + [InlineData( double.NaN, 1, double.NaN, 0.0)] + [InlineData( double.NaN, 2, double.NaN, 0.0)] + [InlineData( double.NaN, 3, double.NaN, 0.0)] + [InlineData( double.NaN, 4, double.NaN, 0.0)] + [InlineData( double.NaN, 5, double.NaN, 0.0)] + [InlineData( 0.0, -5, double.PositiveInfinity, 0.0)] + [InlineData( 0.0, -4, double.PositiveInfinity, 0.0)] + [InlineData( 0.0, -3, double.PositiveInfinity, 0.0)] + [InlineData( 0.0, -2, double.PositiveInfinity, 0.0)] + [InlineData( 0.0, -1, double.PositiveInfinity, 0.0)] + [InlineData( 0.0, 0, double.NaN, 0.0)] + [InlineData( 0.0, 1, 0.0, 0.0)] + [InlineData( 0.0, 2, 0.0, 0.0)] + [InlineData( 0.0, 3, 0.0, 0.0)] + [InlineData( 0.0, 4, 0.0, 0.0)] + [InlineData( 0.0, 5, 0.0, 0.0)] + [InlineData( 1.0, -5, 1.0, 0.0)] + [InlineData( 1.0, -4, 1.0, 0.0)] + [InlineData( 1.0, -3, 1.0, 0.0)] + [InlineData( 1.0, -2, 1.0, 0.0)] + [InlineData( 1.0, -1, 1.0, 0.0)] + [InlineData( 1.0, 0, double.NaN, 0.0)] + [InlineData( 1.0, 1, 1.0, 0.0)] + [InlineData( 1.0, 2, 1.0, 0.0)] + [InlineData( 1.0, 3, 1.0, 0.0)] + [InlineData( 1.0, 4, 1.0, 0.0)] + [InlineData( 1.0, 5, 1.0, 0.0)] + [InlineData( 2.7182818284590452, -5, 0.8187307530779819, CrossPlatformMachineEpsilon64 * 10)] + [InlineData( 2.7182818284590452, -4, 0.7788007830714049, CrossPlatformMachineEpsilon64 * 10)] + [InlineData( 2.7182818284590452, -3, 0.7165313105737893, CrossPlatformMachineEpsilon64 * 10)] + [InlineData( 2.7182818284590452, -2, 0.6065306597126334, CrossPlatformMachineEpsilon64 * 10)] + [InlineData( 2.7182818284590452, -1, 0.3678794411714423, CrossPlatformMachineEpsilon64 * 10)] + [InlineData( 2.7182818284590452, 0, double.NaN, 0.0)] + [InlineData( 2.7182818284590452, 1, 2.7182818284590452, 0.0)] + [InlineData( 2.7182818284590452, 2, 1.6487212707001281, CrossPlatformMachineEpsilon64 * 10)] + [InlineData( 2.7182818284590452, 3, 1.3956124250860895, CrossPlatformMachineEpsilon64 * 10)] + [InlineData( 2.7182818284590452, 4, 1.2840254166877415, CrossPlatformMachineEpsilon64 * 10)] + [InlineData( 2.7182818284590452, 5, 1.2214027581601698, CrossPlatformMachineEpsilon64 * 10)] + [InlineData( double.PositiveInfinity, -5, 0.0f, 0.0)] + [InlineData( double.PositiveInfinity, -4, 0.0f, 0.0)] + [InlineData( double.PositiveInfinity, -3, 0.0f, 0.0)] + [InlineData( double.PositiveInfinity, -2, 0.0f, 0.0)] + [InlineData( double.PositiveInfinity, -1, 0.0f, 0.0)] + [InlineData( double.PositiveInfinity, 0, double.NaN, 0.0)] + [InlineData( double.PositiveInfinity, 1, double.PositiveInfinity, 0.0)] + [InlineData( double.PositiveInfinity, 2, double.PositiveInfinity, 0.0)] + [InlineData( double.PositiveInfinity, 3, double.PositiveInfinity, 0.0)] + [InlineData( double.PositiveInfinity, 4, double.PositiveInfinity, 0.0)] + [InlineData( double.PositiveInfinity, 5, double.PositiveInfinity, 0.0)] + public static void Root64(double x, int n, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, NFloat.Root((NFloat)x, n), allowedVariance); + } } } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index 6128d31e83f..a26dbe17f6f 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -2127,7 +2127,7 @@ public partial class DivideByZeroException : System.ArithmeticException public static double Clamp(double value, double min, double max) { throw null; } public int CompareTo(double value) { throw null; } public int CompareTo(object? value) { throw null; } - public static double CopySign(double x, double y) { throw null; } + public static double CopySign(double value, double sign) { throw null; } public static double Cos(double x) { throw null; } public static double Cosh(double x) { throw null; } public bool Equals(double obj) { throw null; } @@ -2142,6 +2142,7 @@ public partial class DivideByZeroException : System.ArithmeticException public static double FusedMultiplyAdd(double left, double right, double addend) { throw null; } public override int GetHashCode() { throw null; } public System.TypeCode GetTypeCode() { throw null; } + public static double Hypot(double x, double y) { throw null; } public static double Ieee754Remainder(double left, double right) { throw null; } public static int ILogB(double x) { throw null; } public static bool IsEvenInteger(double value) { throw null; } @@ -2188,6 +2189,7 @@ public partial class DivideByZeroException : System.ArithmeticException public static double Pow(double x, double y) { throw null; } public static double ReciprocalEstimate(double x) { throw null; } public static double ReciprocalSqrtEstimate(double x) { throw null; } + public static double Root(double x, int n) { throw null; } public static double Round(double x) { throw null; } public static double Round(double x, int digits) { throw null; } public static double Round(double x, int digits, System.MidpointRounding mode) { throw null; } @@ -2748,7 +2750,7 @@ public partial class GopherStyleUriParser : System.UriParser public static System.Half Clamp(System.Half value, System.Half min, System.Half max) { throw null; } public int CompareTo(System.Half other) { throw null; } public int CompareTo(object? obj) { throw null; } - public static System.Half CopySign(System.Half x, System.Half y) { throw null; } + public static System.Half CopySign(System.Half value, System.Half sign) { throw null; } public static System.Half Cos(System.Half x) { throw null; } public static System.Half Cosh(System.Half x) { throw null; } public bool Equals(System.Half other) { throw null; } @@ -2762,6 +2764,7 @@ public partial class GopherStyleUriParser : System.UriParser public static System.Half Floor(System.Half x) { throw null; } public static System.Half FusedMultiplyAdd(System.Half left, System.Half right, System.Half addend) { throw null; } public override int GetHashCode() { throw null; } + public static System.Half Hypot(System.Half x, System.Half y) { throw null; } public static System.Half Ieee754Remainder(System.Half left, System.Half right) { throw null; } public static int ILogB(System.Half x) { throw null; } public static bool IsEvenInteger(System.Half value) { throw null; } @@ -2877,6 +2880,7 @@ public partial class GopherStyleUriParser : System.UriParser public static System.Half Pow(System.Half x, System.Half y) { throw null; } public static System.Half ReciprocalEstimate(System.Half x) { throw null; } public static System.Half ReciprocalSqrtEstimate(System.Half x) { throw null; } + public static System.Half Root(System.Half x, int n) { throw null; } public static System.Half Round(System.Half x) { throw null; } public static System.Half Round(System.Half x, int digits) { throw null; } public static System.Half Round(System.Half x, int digits, System.MidpointRounding mode) { throw null; } @@ -4718,7 +4722,7 @@ public sealed partial class SerializableAttribute : System.Attribute public static float Clamp(float value, float min, float max) { throw null; } public int CompareTo(object? value) { throw null; } public int CompareTo(float value) { throw null; } - public static float CopySign(float x, float y) { throw null; } + public static float CopySign(float value, float sign) { throw null; } public static float Cos(float x) { throw null; } public static float Cosh(float x) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } @@ -4733,6 +4737,7 @@ public sealed partial class SerializableAttribute : System.Attribute public static float FusedMultiplyAdd(float left, float right, float addend) { throw null; } public override int GetHashCode() { throw null; } public System.TypeCode GetTypeCode() { throw null; } + public static float Hypot(float x, float y) { throw null; } public static float Ieee754Remainder(float left, float right) { throw null; } public static int ILogB(float x) { throw null; } public static bool IsEvenInteger(float value) { throw null; } @@ -4779,6 +4784,7 @@ public sealed partial class SerializableAttribute : System.Attribute public static float Pow(float x, float y) { throw null; } public static float ReciprocalEstimate(float x) { throw null; } public static float ReciprocalSqrtEstimate(float x) { throw null; } + public static float Root(float x, int n) { 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; } @@ -10516,6 +10522,8 @@ public partial interface IPowerFunctions where TSelf : System.Numerics.IP public partial interface IRootFunctions where TSelf : System.Numerics.IRootFunctions, System.Numerics.INumberBase { static abstract TSelf Cbrt(TSelf x); + static abstract TSelf Hypot(TSelf x, TSelf y); + static abstract TSelf Root(TSelf x, int n); static abstract TSelf Sqrt(TSelf x); } public partial interface IShiftOperators where TSelf : System.Numerics.IShiftOperators diff --git a/src/libraries/System.Runtime/tests/System/DoubleTests.cs b/src/libraries/System.Runtime/tests/System/DoubleTests.cs index ad3b09645ad..d849aac40f5 100644 --- a/src/libraries/System.Runtime/tests/System/DoubleTests.cs +++ b/src/libraries/System.Runtime/tests/System/DoubleTests.cs @@ -156,6 +156,67 @@ public static void GetTypeCode_Invoke_ReturnsDouble() Assert.Equal(TypeCode.Double, 0.0.GetTypeCode()); } + [Theory] + [InlineData(double.NaN, double.NaN, double.NaN, 0.0)] + [InlineData(double.NaN, 0.0f, double.NaN, 0.0)] + [InlineData(double.NaN, 1.0f, double.NaN, 0.0)] + [InlineData(double.NaN, 2.7182818284590452, double.NaN, 0.0)] + [InlineData(double.NaN, 10.0, double.NaN, 0.0)] + [InlineData(0.0, 0.0, 0.0, 0.0)] + [InlineData(0.0, 1.0, 1.0, 0.0)] + [InlineData(0.0, 1.5707963267948966, 1.5707963267948966, 0.0)] + [InlineData(0.0, 2.0, 2.0, 0.0)] + [InlineData(0.0, 2.7182818284590452, 2.7182818284590452, 0.0)] + [InlineData(0.0, 3.0, 3.0, 0.0)] + [InlineData(0.0, 10.0, 10.0, 0.0)] + [InlineData(1.0, 1.0, 1.4142135623730950, CrossPlatformMachineEpsilon * 10)] + [InlineData(2.7182818284590452, 0.31830988618379067, 2.7368553638387594, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (1 / pi) + [InlineData(2.7182818284590452, 0.43429448190325183, 2.7527563996732919, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (log10(e)) + [InlineData(2.7182818284590452, 0.63661977236758134, 2.7918346715914253, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (2 / pi) + [InlineData(2.7182818284590452, 0.69314718055994531, 2.8052645352709344, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (ln(2)) + [InlineData(2.7182818284590452, 0.70710678118654752, 2.8087463571726533, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (1 / sqrt(2)) + [InlineData(2.7182818284590452, 0.78539816339744831, 2.8294710413783590, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (pi / 4) + [InlineData(2.7182818284590452, 1.0, 2.8963867315900082, CrossPlatformMachineEpsilon * 10)] // x: (e) + [InlineData(2.7182818284590452, 1.1283791670955126, 2.9431778138036127, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (2 / sqrt(pi)) + [InlineData(2.7182818284590452, 1.4142135623730950, 3.0641566701020120, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (sqrt(2)) + [InlineData(2.7182818284590452, 1.4426950408889634, 3.0774055761202907, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (log2(e)) + [InlineData(2.7182818284590452, 1.5707963267948966, 3.1394995141268918, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (pi / 2) + [InlineData(2.7182818284590452, 2.3025850929940457, 3.5624365551415857, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (ln(10)) + [InlineData(2.7182818284590452, 2.7182818284590452, 3.8442310281591168, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (e) + [InlineData(2.7182818284590452, 3.1415926535897932, 4.1543544023133136, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (pi) + [InlineData(10.0, 0.31830988618379067, 10.005064776584025, CrossPlatformMachineEpsilon * 100)] // y: (1 / pi) + [InlineData(10.0, 0.43429448190325183, 10.009426142242702, CrossPlatformMachineEpsilon * 100)] // y: (log10(e)) + [InlineData(10.0, 0.63661977236758134, 10.020243746265325, CrossPlatformMachineEpsilon * 100)] // y: (2 / pi) + [InlineData(10.0, 0.69314718055994531, 10.023993865417028, CrossPlatformMachineEpsilon * 100)] // y: (ln(2)) + [InlineData(10.0, 0.70710678118654752, 10.024968827881711, CrossPlatformMachineEpsilon * 100)] // y: (1 / sqrt(2)) + [InlineData(10.0, 0.78539816339744831, 10.030795096853892, CrossPlatformMachineEpsilon * 100)] // y: (pi / 4) + [InlineData(10.0, 1.0, 10.049875621120890, CrossPlatformMachineEpsilon * 100)] // + [InlineData(10.0, 1.1283791670955126, 10.063460614755501, CrossPlatformMachineEpsilon * 100)] // y: (2 / sqrt(pi)) + [InlineData(10.0, 1.4142135623730950, 10.099504938362078, CrossPlatformMachineEpsilon * 100)] // y: (sqrt(2)) + [InlineData(10.0, 1.4426950408889634, 10.103532500121213, CrossPlatformMachineEpsilon * 100)] // y: (log2(e)) + [InlineData(10.0, 1.5707963267948966, 10.122618292728040, CrossPlatformMachineEpsilon * 100)] // y: (pi / 2) + [InlineData(10.0, 2.3025850929940457, 10.261671311754163, CrossPlatformMachineEpsilon * 100)] // y: (ln(10)) + [InlineData(10.0, 2.7182818284590452, 10.362869105558106, CrossPlatformMachineEpsilon * 100)] // y: (e) + [InlineData(10.0, 3.1415926535897932, 10.481870272097884, CrossPlatformMachineEpsilon * 100)] // y: (pi) + [InlineData(double.PositiveInfinity, double.NaN, double.PositiveInfinity, 0.0)] + [InlineData(double.PositiveInfinity, 0.0, double.PositiveInfinity, 0.0)] + [InlineData(double.PositiveInfinity, 1.0, double.PositiveInfinity, 0.0)] + [InlineData(double.PositiveInfinity, 2.7182818284590452, double.PositiveInfinity, 0.0)] + [InlineData(double.PositiveInfinity, 10.0, double.PositiveInfinity, 0.0)] + [InlineData(double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Hypot(double x, double y, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, double.Hypot(-x, -y), allowedVariance); + AssertExtensions.Equal(expectedResult, double.Hypot(-x, +y), allowedVariance); + AssertExtensions.Equal(expectedResult, double.Hypot(+x, -y), allowedVariance); + AssertExtensions.Equal(expectedResult, double.Hypot(+x, +y), allowedVariance); + + AssertExtensions.Equal(expectedResult, double.Hypot(-y, -x), allowedVariance); + AssertExtensions.Equal(expectedResult, double.Hypot(-y, +x), allowedVariance); + AssertExtensions.Equal(expectedResult, double.Hypot(+y, -x), allowedVariance); + AssertExtensions.Equal(expectedResult, double.Hypot(+y, +x), allowedVariance); + } + [Theory] [InlineData(double.NegativeInfinity, true)] // Negative Infinity [InlineData(double.MinValue, false)] // Min Negative Normal @@ -558,6 +619,111 @@ public static void PositiveInfinity() Assert.Equal(0x7FF00000_00000000u, BitConverter.DoubleToUInt64Bits(double.PositiveInfinity)); } + [Theory] + [InlineData( double.NegativeInfinity, -5, -0.0, 0.0)] + [InlineData( double.NegativeInfinity, -4, double.NaN, 0.0)] + [InlineData( double.NegativeInfinity, -3, -0.0, 0.0)] + [InlineData( double.NegativeInfinity, -2, double.NaN, 0.0)] + [InlineData( double.NegativeInfinity, -1, -0.0, 0.0)] + [InlineData( double.NegativeInfinity, 0, double.NaN, 0.0)] + [InlineData( double.NegativeInfinity, 1, double.NegativeInfinity, 0.0)] + [InlineData( double.NegativeInfinity, 2, double.NaN, 0.0)] + [InlineData( double.NegativeInfinity, 3, double.NegativeInfinity, 0.0)] + [InlineData( double.NegativeInfinity, 4, double.NaN, 0.0)] + [InlineData( double.NegativeInfinity, 5, double.NegativeInfinity, 0.0)] + [InlineData(-2.7182818284590452, -5, -0.8187307530779819, CrossPlatformMachineEpsilon * 10)] + [InlineData(-2.7182818284590452, -4, double.NaN, 0.0)] + [InlineData(-2.7182818284590452, -3, -0.7165313105737893, CrossPlatformMachineEpsilon * 10)] + [InlineData(-2.7182818284590452, -2, double.NaN, 0.0)] + [InlineData(-2.7182818284590452, -1, -0.3678794411714423, CrossPlatformMachineEpsilon * 10)] + [InlineData(-2.7182818284590452, 0, double.NaN, 0.0)] + [InlineData(-2.7182818284590452, 1, -2.7182818284590452, CrossPlatformMachineEpsilon * 10)] + [InlineData(-2.7182818284590452, 2, double.NaN, 0.0)] + [InlineData(-2.7182818284590452, 3, -1.3956124250860895, CrossPlatformMachineEpsilon * 10)] + [InlineData(-2.7182818284590452, 4, double.NaN, 0.0)] + [InlineData(-2.7182818284590452, 5, -1.2214027581601698, CrossPlatformMachineEpsilon * 10)] + [InlineData(-1.0, -5, -1.0, 0.0)] + [InlineData(-1.0, -4, double.NaN, 0.0)] + [InlineData(-1.0, -3, -1.0, 0.0)] + [InlineData(-1.0, -2, double.NaN, 0.0)] + [InlineData(-1.0, -1, -1.0, 0.0)] + [InlineData(-1.0, 0, double.NaN, 0.0)] + [InlineData(-1.0, 1, -1.0, 0.0)] + [InlineData(-1.0, 2, double.NaN, 0.0)] + [InlineData(-1.0, 3, -1.0, 0.0)] + [InlineData(-1.0, 4, double.NaN, 0.0)] + [InlineData(-1.0, 5, -1.0, 0.0)] + [InlineData(-0.0, -5, double.NegativeInfinity, 0.0)] + [InlineData(-0.0, -4, double.PositiveInfinity, 0.0)] + [InlineData(-0.0, -3, double.NegativeInfinity, 0.0)] + [InlineData(-0.0, -2, double.PositiveInfinity, 0.0)] + [InlineData(-0.0, -1, double.NegativeInfinity, 0.0)] + [InlineData(-0.0, 0, double.NaN, 0.0)] + [InlineData(-0.0, 1, -0.0, 0.0)] + [InlineData(-0.0, 2, 0.0, 0.0)] + [InlineData(-0.0, 3, -0.0, 0.0)] + [InlineData(-0.0, 4, 0.0, 0.0)] + [InlineData(-0.0, 5, -0.0, 0.0)] + [InlineData( double.NaN, -5, double.NaN, 0.0)] + [InlineData( double.NaN, -4, double.NaN, 0.0)] + [InlineData( double.NaN, -3, double.NaN, 0.0)] + [InlineData( double.NaN, -2, double.NaN, 0.0)] + [InlineData( double.NaN, -1, double.NaN, 0.0)] + [InlineData( double.NaN, 0, double.NaN, 0.0)] + [InlineData( double.NaN, 1, double.NaN, 0.0)] + [InlineData( double.NaN, 2, double.NaN, 0.0)] + [InlineData( double.NaN, 3, double.NaN, 0.0)] + [InlineData( double.NaN, 4, double.NaN, 0.0)] + [InlineData( double.NaN, 5, double.NaN, 0.0)] + [InlineData( 0.0, -5, double.PositiveInfinity, 0.0)] + [InlineData( 0.0, -4, double.PositiveInfinity, 0.0)] + [InlineData( 0.0, -3, double.PositiveInfinity, 0.0)] + [InlineData( 0.0, -2, double.PositiveInfinity, 0.0)] + [InlineData( 0.0, -1, double.PositiveInfinity, 0.0)] + [InlineData( 0.0, 0, double.NaN, 0.0)] + [InlineData( 0.0, 1, 0.0, 0.0)] + [InlineData( 0.0, 2, 0.0, 0.0)] + [InlineData( 0.0, 3, 0.0, 0.0)] + [InlineData( 0.0, 4, 0.0, 0.0)] + [InlineData( 0.0, 5, 0.0, 0.0)] + [InlineData( 1.0, -5, 1.0, 0.0)] + [InlineData( 1.0, -4, 1.0, 0.0)] + [InlineData( 1.0, -3, 1.0, 0.0)] + [InlineData( 1.0, -2, 1.0, 0.0)] + [InlineData( 1.0, -1, 1.0, 0.0)] + [InlineData( 1.0, 0, double.NaN, 0.0)] + [InlineData( 1.0, 1, 1.0, 0.0)] + [InlineData( 1.0, 2, 1.0, 0.0)] + [InlineData( 1.0, 3, 1.0, 0.0)] + [InlineData( 1.0, 4, 1.0, 0.0)] + [InlineData( 1.0, 5, 1.0, 0.0)] + [InlineData( 2.7182818284590452, -5, 0.8187307530779819, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.7182818284590452, -4, 0.7788007830714049, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.7182818284590452, -3, 0.7165313105737893, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.7182818284590452, -2, 0.6065306597126334, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.7182818284590452, -1, 0.3678794411714423, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.7182818284590452, 0, double.NaN, 0.0)] + [InlineData( 2.7182818284590452, 1, 2.7182818284590452, 0.0)] + [InlineData( 2.7182818284590452, 2, 1.6487212707001281, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.7182818284590452, 3, 1.3956124250860895, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.7182818284590452, 4, 1.2840254166877415, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.7182818284590452, 5, 1.2214027581601698, CrossPlatformMachineEpsilon * 10)] + [InlineData( double.PositiveInfinity, -5, 0.0f, 0.0)] + [InlineData( double.PositiveInfinity, -4, 0.0f, 0.0)] + [InlineData( double.PositiveInfinity, -3, 0.0f, 0.0)] + [InlineData( double.PositiveInfinity, -2, 0.0f, 0.0)] + [InlineData( double.PositiveInfinity, -1, 0.0f, 0.0)] + [InlineData( double.PositiveInfinity, 0, double.NaN, 0.0)] + [InlineData( double.PositiveInfinity, 1, double.PositiveInfinity, 0.0)] + [InlineData( double.PositiveInfinity, 2, double.PositiveInfinity, 0.0)] + [InlineData( double.PositiveInfinity, 3, double.PositiveInfinity, 0.0)] + [InlineData( double.PositiveInfinity, 4, double.PositiveInfinity, 0.0)] + [InlineData( double.PositiveInfinity, 5, double.PositiveInfinity, 0.0)] + public static void Root(double x, int n, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, double.Root(x, n), allowedVariance); + } + public static IEnumerable ToString_TestData() { yield return new object[] { -4567.0, "G", null, "-4567" }; diff --git a/src/libraries/System.Runtime/tests/System/HalfTests.cs b/src/libraries/System.Runtime/tests/System/HalfTests.cs index 9970f291eaf..994536e4108 100644 --- a/src/libraries/System.Runtime/tests/System/HalfTests.cs +++ b/src/libraries/System.Runtime/tests/System/HalfTests.cs @@ -1121,8 +1121,8 @@ public static IEnumerable MaxMagnitudeNumber_TestData() yield return new object[] { Half.MinValue, Half.MaxValue, Half.MaxValue }; yield return new object[] { Half.MaxValue, Half.MinValue, Half.MaxValue }; yield return new object[] { Half.NaN, Half.NaN, Half.NaN }; - yield return new object[] { Half.NaN, (Half)1.0f, (Half)1.0f }; - yield return new object[] { (Half)1.0f, Half.NaN, (Half)1.0f }; + yield return new object[] { Half.NaN, (Half)Half.One, (Half)Half.One }; + yield return new object[] { (Half)Half.One, Half.NaN, (Half)Half.One }; yield return new object[] { Half.PositiveInfinity, Half.NaN, Half.PositiveInfinity }; yield return new object[] { Half.NegativeInfinity, Half.NaN, Half.NegativeInfinity }; yield return new object[] { Half.NaN, Half.PositiveInfinity, Half.PositiveInfinity }; @@ -1149,8 +1149,8 @@ public static IEnumerable MaxNumber_TestData() yield return new object[] { Half.MinValue, Half.MaxValue, Half.MaxValue }; yield return new object[] { Half.MaxValue, Half.MinValue, Half.MaxValue }; yield return new object[] { Half.NaN, Half.NaN, Half.NaN }; - yield return new object[] { Half.NaN, (Half)1.0f, (Half)1.0f }; - yield return new object[] { (Half)1.0f, Half.NaN, (Half)1.0f }; + yield return new object[] { Half.NaN, (Half)Half.One, (Half)Half.One }; + yield return new object[] { (Half)Half.One, Half.NaN, (Half)Half.One }; yield return new object[] { Half.PositiveInfinity, Half.NaN, Half.PositiveInfinity }; yield return new object[] { Half.NegativeInfinity, Half.NaN, Half.NegativeInfinity }; yield return new object[] { Half.NaN, Half.PositiveInfinity, Half.PositiveInfinity }; @@ -1177,8 +1177,8 @@ public static IEnumerable MinMagnitudeNumber_TestData() yield return new object[] { Half.MinValue, Half.MaxValue, Half.MinValue }; yield return new object[] { Half.MaxValue, Half.MinValue, Half.MinValue }; yield return new object[] { Half.NaN, Half.NaN, Half.NaN }; - yield return new object[] { Half.NaN, (Half)1.0f, (Half)1.0f }; - yield return new object[] { (Half)1.0f, Half.NaN, (Half)1.0f }; + yield return new object[] { Half.NaN, (Half)Half.One, (Half)Half.One }; + yield return new object[] { (Half)Half.One, Half.NaN, (Half)Half.One }; yield return new object[] { Half.PositiveInfinity, Half.NaN, Half.PositiveInfinity }; yield return new object[] { Half.NegativeInfinity, Half.NaN, Half.NegativeInfinity }; yield return new object[] { Half.NaN, Half.PositiveInfinity, Half.PositiveInfinity }; @@ -1205,8 +1205,8 @@ public static IEnumerable MinNumber_TestData() yield return new object[] { Half.MinValue, Half.MaxValue, Half.MinValue }; yield return new object[] { Half.MaxValue, Half.MinValue, Half.MinValue }; yield return new object[] { Half.NaN, Half.NaN, Half.NaN }; - yield return new object[] { Half.NaN, (Half)1.0f, (Half)1.0f }; - yield return new object[] { (Half)1.0f, Half.NaN, (Half)1.0f }; + yield return new object[] { Half.NaN, (Half)Half.One, (Half)Half.One }; + yield return new object[] { (Half)Half.One, Half.NaN, (Half)Half.One }; yield return new object[] { Half.PositiveInfinity, Half.NaN, Half.PositiveInfinity }; yield return new object[] { Half.NegativeInfinity, Half.NaN, Half.NegativeInfinity }; yield return new object[] { Half.NaN, Half.PositiveInfinity, Half.PositiveInfinity }; @@ -1228,7 +1228,7 @@ public static void MinNumberTest(Half x, Half y, Half expectedResult) public static IEnumerable ExpM1_TestData() { - yield return new object[] { Half.NegativeInfinity, (Half)(-1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { Half.NegativeInfinity, (Half)(-Half.One), CrossPlatformMachineEpsilon * (Half)10 }; yield return new object[] { (Half)(-3.14159265f), (Half)(-0.956786082f), CrossPlatformMachineEpsilon }; // value: -(pi) yield return new object[] { (Half)(-2.71828183f), (Half)(-0.934011964f), CrossPlatformMachineEpsilon }; // value: -(e) yield return new object[] { (Half)(-2.30258509f), (Half)(-0.9f), CrossPlatformMachineEpsilon }; // value: -(ln(10)) @@ -1236,7 +1236,7 @@ public static IEnumerable ExpM1_TestData() yield return new object[] { (Half)(-1.44269504f), (Half)(-0.763709912f), CrossPlatformMachineEpsilon }; // value: -(log2(e)) yield return new object[] { (Half)(-1.41421356f), (Half)(-0.756883266f), CrossPlatformMachineEpsilon }; // value: -(sqrt(2)) yield return new object[] { (Half)(-1.12837917f), (Half)(-0.676442736f), CrossPlatformMachineEpsilon }; // value: -(2 / sqrt(pi)) - yield return new object[] { (Half)(-1.0f), (Half)(-0.632120559f), CrossPlatformMachineEpsilon }; + yield return new object[] { (Half)(-Half.One), (Half)(-0.632120559f), CrossPlatformMachineEpsilon }; yield return new object[] { (Half)(-0.785398163f), (Half)(-0.544061872f), CrossPlatformMachineEpsilon }; // value: -(pi / 4) yield return new object[] { (Half)(-0.707106781f), (Half)(-0.506931309f), CrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2)) yield return new object[] { (Half)(-0.693147181f), (Half)(-0.5f), CrossPlatformMachineEpsilon }; // value: -(ln(2)) @@ -1249,10 +1249,10 @@ public static IEnumerable ExpM1_TestData() yield return new object[] { (Half)( 0.318309886f), (Half)( 0.374802227f), CrossPlatformMachineEpsilon }; // value: (1 / pi) yield return new object[] { (Half)( 0.434294482f), (Half)( 0.543873444f), CrossPlatformMachineEpsilon }; // value: (log10(e)) yield return new object[] { (Half)( 0.636619772f), (Half)( 0.890081165f), CrossPlatformMachineEpsilon }; // value: (2 / pi) - yield return new object[] { (Half)( 0.693147181f), (Half)( 1.0f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (ln(2)) + yield return new object[] { (Half)( 0.693147181f), (Half)( Half.One), CrossPlatformMachineEpsilon * (Half)10 }; // value: (ln(2)) yield return new object[] { (Half)( 0.707106781f), (Half)( 1.02811498f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (1 / sqrt(2)) yield return new object[] { (Half)( 0.785398163f), (Half)( 1.19328005f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (pi / 4) - yield return new object[] { (Half)( 1.0f), (Half)( 1.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)( Half.One), (Half)( 1.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; yield return new object[] { (Half)( 1.12837917f), (Half)( 2.09064302f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (2 / sqrt(pi)) yield return new object[] { (Half)( 1.41421356f), (Half)( 3.11325038f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (sqrt(2)) yield return new object[] { (Half)( 1.44269504f), (Half)( 3.23208611f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (log2(e)) @@ -1280,23 +1280,23 @@ public static IEnumerable Exp2_TestData() yield return new object[] { (Half)(-1.44269504f), (Half)(0.367879441f), CrossPlatformMachineEpsilon }; // value: -(log2(e)) yield return new object[] { (Half)(-1.41421356f), (Half)(0.375214227f), CrossPlatformMachineEpsilon }; // value: -(sqrt(2)) yield return new object[] { (Half)(-1.12837917f), (Half)(0.457429347f), CrossPlatformMachineEpsilon }; // value: -(2 / sqrt(pi)) - yield return new object[] { (Half)(-1.0f), (Half)(0.5f), CrossPlatformMachineEpsilon }; + yield return new object[] { (Half)(-Half.One), (Half)(0.5f), CrossPlatformMachineEpsilon }; yield return new object[] { (Half)(-0.785398163f), (Half)(0.580191810f), CrossPlatformMachineEpsilon }; // value: -(pi / 4) yield return new object[] { (Half)(-0.707106781f), (Half)(0.612547327f), CrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2)) yield return new object[] { (Half)(-0.693147181f), (Half)(0.618503138f), CrossPlatformMachineEpsilon }; // value: -(ln(2)) yield return new object[] { (Half)(-0.636619772f), (Half)(0.643218242f), CrossPlatformMachineEpsilon }; // value: -(2 / pi) yield return new object[] { (Half)(-0.434294482f), (Half)(0.740055574f), CrossPlatformMachineEpsilon }; // value: -(log10(e)) yield return new object[] { (Half)(-0.318309886f), (Half)(0.802008879f), CrossPlatformMachineEpsilon }; // value: -(1 / pi) - yield return new object[] { (Half)(-0.0f), (Half)(1.0f), (Half)0.0f }; + yield return new object[] { (Half)(-0.0f), (Half)(Half.One), (Half)0.0f }; yield return new object[] { Half.NaN, Half.NaN, (Half)0.0f }; - yield return new object[] { (Half)( 0.0f), (Half)(1.0f), (Half)0.0f }; + yield return new object[] { (Half)( 0.0f), (Half)(Half.One), (Half)0.0f }; yield return new object[] { (Half)( 0.318309886f), (Half)(1.24686899f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (1 / pi) yield return new object[] { (Half)( 0.434294482f), (Half)(1.35124987f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (log10(e)) yield return new object[] { (Half)( 0.636619772f), (Half)(1.55468228f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (2 / pi) yield return new object[] { (Half)( 0.693147181f), (Half)(1.61680667f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (ln(2)) yield return new object[] { (Half)( 0.707106781f), (Half)(1.63252692f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (1 / sqrt(2)) yield return new object[] { (Half)( 0.785398163f), (Half)(1.72356793f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (pi / 4) - yield return new object[] { (Half)( 1.0f), (Half)(2.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)( Half.One), (Half)(2.0f), CrossPlatformMachineEpsilon * (Half)10 }; yield return new object[] { (Half)( 1.12837917f), (Half)(2.18612996f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (2 / sqrt(pi)) yield return new object[] { (Half)( 1.41421356f), (Half)(2.66514414f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (sqrt(2)) yield return new object[] { (Half)( 1.44269504f), (Half)(2.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (log2(e)) @@ -1316,7 +1316,7 @@ public static void Exp2Test(Half value, Half expectedResult, Half allowedVarianc public static IEnumerable Exp2M1_TestData() { - yield return new object[] { Half.NegativeInfinity, (Half)(-1.0f), (Half)0.0f }; + yield return new object[] { Half.NegativeInfinity, (Half)(-Half.One), (Half)0.0f }; yield return new object[] { (Half)(-3.14159265f), (Half)(-0.886685268f), CrossPlatformMachineEpsilon }; // value: -(pi) yield return new object[] { (Half)(-2.71828183f), (Half)(-0.848044777f), CrossPlatformMachineEpsilon }; // value: -(e) yield return new object[] { (Half)(-2.30258509f), (Half)(-0.797300434f), CrossPlatformMachineEpsilon }; // value: -(ln(10)) @@ -1324,7 +1324,7 @@ public static IEnumerable Exp2M1_TestData() yield return new object[] { (Half)(-1.44269504f), (Half)(-0.632120559f), CrossPlatformMachineEpsilon }; // value: -(log2(e)) yield return new object[] { (Half)(-1.41421356f), (Half)(-0.624785773f), CrossPlatformMachineEpsilon }; // value: -(sqrt(2)) yield return new object[] { (Half)(-1.12837917f), (Half)(-0.542570653f), CrossPlatformMachineEpsilon }; // value: -(2 / sqrt(pi)) - yield return new object[] { (Half)(-1.0f), (Half)(-0.5f), CrossPlatformMachineEpsilon }; + yield return new object[] { (Half)(-Half.One), (Half)(-0.5f), CrossPlatformMachineEpsilon }; yield return new object[] { (Half)(-0.785398163f), (Half)(-0.419808190f), CrossPlatformMachineEpsilon }; // value: -(pi / 4) yield return new object[] { (Half)(-0.707106781f), (Half)(-0.387452673f), CrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2)) yield return new object[] { (Half)(-0.693147181f), (Half)(-0.381496862f), CrossPlatformMachineEpsilon }; // value: -(ln(2)) @@ -1340,7 +1340,7 @@ public static IEnumerable Exp2M1_TestData() yield return new object[] { (Half)( 0.693147181f), (Half)( 0.616806672f), CrossPlatformMachineEpsilon }; // value: (ln(2)) yield return new object[] { (Half)( 0.707106781f), (Half)( 0.632526919f), CrossPlatformMachineEpsilon }; // value: (1 / sqrt(2)) yield return new object[] { (Half)( 0.785398163f), (Half)( 0.723567934f), CrossPlatformMachineEpsilon }; // value: (pi / 4) - yield return new object[] { (Half)( 1.0f), (Half)( 1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)( Half.One), (Half)( Half.One), CrossPlatformMachineEpsilon * (Half)10 }; yield return new object[] { (Half)( 1.12837917f), (Half)( 1.18612996f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (2 / sqrt(pi)) yield return new object[] { (Half)( 1.41421356f), (Half)( 1.66514414f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (sqrt(2)) yield return new object[] { (Half)( 1.44269504f), (Half)( 1.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (log2(e)) @@ -1368,23 +1368,23 @@ public static IEnumerable Exp10_TestData() yield return new object[] { (Half)(-1.44269504f), (Half)0.0360831928f, CrossPlatformMachineEpsilon / (Half)10 }; // value: -(log2(e)) yield return new object[] { (Half)(-1.41421356f), (Half)0.0385288847f, CrossPlatformMachineEpsilon / (Half)10 }; // value: -(sqrt(2)) yield return new object[] { (Half)(-1.12837917f), (Half)0.0744082059f, CrossPlatformMachineEpsilon / (Half)10 }; // value: -(2 / sqrt(pi)) - yield return new object[] { (Half)(-1.0f), (Half)0.1f, CrossPlatformMachineEpsilon }; + yield return new object[] { (Half)(-Half.One), (Half)0.1f, CrossPlatformMachineEpsilon }; yield return new object[] { (Half)(-0.785398163f), (Half)0.163908636f, CrossPlatformMachineEpsilon }; // value: -(pi / 4) yield return new object[] { (Half)(-0.707106781f), (Half)0.196287760f, CrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2)) yield return new object[] { (Half)(-0.693147181f), (Half)0.202699566f, CrossPlatformMachineEpsilon }; // value: -(ln(2)) yield return new object[] { (Half)(-0.636619772f), (Half)0.230876765f, CrossPlatformMachineEpsilon }; // value: -(2 / pi) yield return new object[] { (Half)(-0.434294482f), (Half)0.367879441f, CrossPlatformMachineEpsilon }; // value: -(log10(e)) yield return new object[] { (Half)(-0.318309886f), (Half)0.480496373f, CrossPlatformMachineEpsilon }; // value: -(1 / pi) - yield return new object[] { (Half)(-0.0f), (Half)1.0f, (Half)0.0f }; + yield return new object[] { (Half)(-0.0f), (Half)Half.One, (Half)0.0f }; yield return new object[] { Half.NaN, Half.NaN, (Half)0.0f }; - yield return new object[] { (Half)( 0.0f), (Half)1.0f, (Half)0.0f }; + yield return new object[] { (Half)( 0.0f), (Half)Half.One, (Half)0.0f }; yield return new object[] { (Half)( 0.318309886f), (Half)2.08118116f, CrossPlatformMachineEpsilon * (Half)10 }; // value: (1 / pi) yield return new object[] { (Half)( 0.434294482f), (Half)2.71828183f, CrossPlatformMachineEpsilon * (Half)10 }; // value: (log10(e)) yield return new object[] { (Half)( 0.636619772f), (Half)4.33131503f, CrossPlatformMachineEpsilon * (Half)10 }; // value: (2 / pi) yield return new object[] { (Half)( 0.693147181f), (Half)4.93340967f, CrossPlatformMachineEpsilon * (Half)10 }; // value: (ln(2)) yield return new object[] { (Half)( 0.707106781f), (Half)5.09456117f, CrossPlatformMachineEpsilon * (Half)10 }; // value: (1 / sqrt(2)) yield return new object[] { (Half)( 0.785398163f), (Half)6.10095980f, CrossPlatformMachineEpsilon * (Half)10 }; // value: (pi / 4) - yield return new object[] { (Half)( 1.0f), (Half)10.0f, CrossPlatformMachineEpsilon * (Half)100 }; + yield return new object[] { (Half)( Half.One), (Half)10.0f, CrossPlatformMachineEpsilon * (Half)100 }; yield return new object[] { (Half)( 1.12837917f), (Half)13.4393779f, CrossPlatformMachineEpsilon * (Half)100 }; // value: (2 / sqrt(pi)) yield return new object[] { (Half)( 1.41421356f), (Half)25.9545535f, CrossPlatformMachineEpsilon * (Half)100 }; // value: (sqrt(2)) yield return new object[] { (Half)( 1.44269504f), (Half)27.7137338f, CrossPlatformMachineEpsilon * (Half)100 }; // value: (log2(e)) @@ -1404,7 +1404,7 @@ public static void Exp10Test(Half value, Half expectedResult, Half allowedVarian public static IEnumerable Exp10M1_TestData() { - yield return new object[] { Half.NegativeInfinity, (Half)(-1.0f), (Half)0.0f }; + yield return new object[] { Half.NegativeInfinity, (Half)(-Half.One), (Half)0.0f }; yield return new object[] { (Half)(-3.14159265f), (Half)(-0.999278216f), CrossPlatformMachineEpsilon }; // value: -(pi) yield return new object[] { (Half)(-2.71828183f), (Half)(-0.998086986f), CrossPlatformMachineEpsilon }; // value: -(e) yield return new object[] { (Half)(-2.30258509f), (Half)(-0.995017872f), CrossPlatformMachineEpsilon }; // value: -(ln(10)) @@ -1412,7 +1412,7 @@ public static IEnumerable Exp10M1_TestData() yield return new object[] { (Half)(-1.44269504f), (Half)(-0.963916807f), CrossPlatformMachineEpsilon }; // value: -(log2(e)) yield return new object[] { (Half)(-1.41421356f), (Half)(-0.961471115f), CrossPlatformMachineEpsilon }; // value: -(sqrt(2)) yield return new object[] { (Half)(-1.12837917f), (Half)(-0.925591794f), CrossPlatformMachineEpsilon }; // value: -(2 / sqrt(pi)) - yield return new object[] { (Half)(-1.0f), (Half)(-0.9f), CrossPlatformMachineEpsilon }; + yield return new object[] { (Half)(-Half.One), (Half)(-0.9f), CrossPlatformMachineEpsilon }; yield return new object[] { (Half)(-0.785398163f), (Half)(-0.836091364f), CrossPlatformMachineEpsilon }; // value: -(pi / 4) yield return new object[] { (Half)(-0.707106781f), (Half)(-0.803712240f), CrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2)) yield return new object[] { (Half)(-0.693147181f), (Half)(-0.797300434f), CrossPlatformMachineEpsilon }; // value: -(ln(2)) @@ -1428,7 +1428,7 @@ public static IEnumerable Exp10M1_TestData() yield return new object[] { (Half)( 0.693147181f), (Half)( 3.93340967f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (ln(2)) yield return new object[] { (Half)( 0.707106781f), (Half)( 4.09456117f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (1 / sqrt(2)) yield return new object[] { (Half)( 0.785398163f), (Half)( 5.10095980f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (pi / 4) - yield return new object[] { (Half)( 1.0f), (Half)( 9.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)( Half.One), (Half)( 9.0f), CrossPlatformMachineEpsilon * (Half)10 }; yield return new object[] { (Half)( 1.12837917f), (Half)( 12.4393779f), CrossPlatformMachineEpsilon * (Half)100 }; // value: (2 / sqrt(pi)) yield return new object[] { (Half)( 1.41421356f), (Half)( 24.9545535f), CrossPlatformMachineEpsilon * (Half)100 }; // value: (sqrt(2)) yield return new object[] { (Half)( 1.44269504f), (Half)( 26.7137338f), CrossPlatformMachineEpsilon * (Half)100 }; // value: (log2(e)) @@ -1453,7 +1453,7 @@ public static IEnumerable LogP1_TestData() yield return new object[] { (Half)(-2.71828183f), Half.NaN, (Half)0.0f }; // value: -(e) yield return new object[] { (Half)(-1.41421356f), Half.NaN, (Half)0.0f }; // value: -(sqrt(2)) yield return new object[] { Half.NaN, Half.NaN, (Half)0.0f }; - yield return new object[] { (Half)(-1.0f), Half.NegativeInfinity, (Half)0.0f }; + yield return new object[] { (Half)(-Half.One), Half.NegativeInfinity, (Half)0.0f }; yield return new object[] { (Half)(-0.956786082f), (Half)(-3.14159265f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(pi) yield return new object[] { (Half)(-0.934011964f), (Half)(-2.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(e) yield return new object[] { (Half)(-0.9f), (Half)(-2.30258509f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(ln(10)) @@ -1461,7 +1461,7 @@ public static IEnumerable LogP1_TestData() yield return new object[] { (Half)(-0.763709912f), (Half)(-1.44269504f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(log2(e)) yield return new object[] { (Half)(-0.756883266f), (Half)(-1.41421356f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(sqrt(2)) yield return new object[] { (Half)(-0.676442736f), (Half)(-1.12837917f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(2 / sqrt(pi)) - yield return new object[] { (Half)(-0.632120559f), (Half)(-1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)(-0.632120559f), (Half)(-Half.One), CrossPlatformMachineEpsilon * (Half)10 }; yield return new object[] { (Half)(-0.544061872f), (Half)(-0.785398163f), CrossPlatformMachineEpsilon }; // expected: -(pi / 4) yield return new object[] { (Half)(-0.506931309f), (Half)(-0.707106781f), CrossPlatformMachineEpsilon }; // expected: -(1 / sqrt(2)) yield return new object[] { (Half)(-0.5f), (Half)(-0.693147181f), CrossPlatformMachineEpsilon }; // expected: -(ln(2)) @@ -1471,10 +1471,10 @@ public static IEnumerable LogP1_TestData() yield return new object[] { (Half)( 0.374802227f), (Half)( 0.318309886f), CrossPlatformMachineEpsilon }; // expected: (1 / pi) yield return new object[] { (Half)( 0.543873444f), (Half)( 0.434294482f), CrossPlatformMachineEpsilon }; // expected: (log10(e)) yield return new object[] { (Half)( 0.890081165f), (Half)( 0.636619772f), CrossPlatformMachineEpsilon }; // expected: (2 / pi) - yield return new object[] { (Half)( 1.0f), (Half)( 0.693147181f), CrossPlatformMachineEpsilon }; // expected: (ln(2)) + yield return new object[] { (Half)( Half.One), (Half)( 0.693147181f), CrossPlatformMachineEpsilon }; // expected: (ln(2)) yield return new object[] { (Half)( 1.02811498f), (Half)( 0.707106781f), CrossPlatformMachineEpsilon }; // expected: (1 / sqrt(2)) yield return new object[] { (Half)( 1.19328005f), (Half)( 0.785398163f), CrossPlatformMachineEpsilon }; // expected: (pi / 4) - yield return new object[] { (Half)( 1.71828183f), (Half)( 1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)( 1.71828183f), (Half)( Half.One), CrossPlatformMachineEpsilon * (Half)10 }; yield return new object[] { (Half)( 2.09064302f), (Half)( 1.12837917f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (2 / sqrt(pi)) yield return new object[] { (Half)( 3.11325038f), (Half)( 1.41421356f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (sqrt(2)) yield return new object[] { (Half)( 3.23208611f), (Half)( 1.44269504f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (log2(e)) @@ -1496,7 +1496,7 @@ public static IEnumerable Log2P1_TestData() { yield return new object[] { Half.NegativeInfinity, Half.NaN, (Half)0.0f }; yield return new object[] { Half.NaN, Half.NaN, (Half)0.0f }; - yield return new object[] { (Half)(-1.0f), Half.NegativeInfinity, (Half)0.0f }; + yield return new object[] { (Half)(-Half.One), Half.NegativeInfinity, (Half)0.0f }; yield return new object[] { (Half)(-0.886685268f), (Half)(-3.14159265f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(pi) yield return new object[] { (Half)(-0.848044777f), (Half)(-2.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(e) yield return new object[] { (Half)(-0.797300434f), (Half)(-2.30258509f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(ln(10)) @@ -1504,7 +1504,7 @@ public static IEnumerable Log2P1_TestData() yield return new object[] { (Half)(-0.632120559f), (Half)(-1.44269504f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(log2(e)) yield return new object[] { (Half)(-0.624785773f), (Half)(-1.41421356f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(sqrt(2)) yield return new object[] { (Half)(-0.542570653f), (Half)(-1.12837917f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(2 / sqrt(pi)) - yield return new object[] { (Half)(-0.5f), (Half)(-1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)(-0.5f), (Half)(-Half.One), CrossPlatformMachineEpsilon * (Half)10 }; yield return new object[] { (Half)(-0.419808190f), (Half)(-0.785398163f), CrossPlatformMachineEpsilon }; // expected: -(pi / 4) yield return new object[] { (Half)(-0.387452673f), (Half)(-0.707106781f), CrossPlatformMachineEpsilon }; // expected: -(1 / sqrt(2)) yield return new object[] { (Half)(-0.381496862f), (Half)(-0.693147181f), CrossPlatformMachineEpsilon }; // expected: -(ln(2)) @@ -1519,7 +1519,7 @@ public static IEnumerable Log2P1_TestData() yield return new object[] { (Half)( 0.616806672f), (Half)( 0.693147181f), CrossPlatformMachineEpsilon }; // expected: (ln(2)) yield return new object[] { (Half)( 0.632526919f), (Half)( 0.707106781f), CrossPlatformMachineEpsilon }; // expected: (1 / sqrt(2)) yield return new object[] { (Half)( 0.723567934f), (Half)( 0.785398163f), CrossPlatformMachineEpsilon }; // expected: (pi / 4) - yield return new object[] { (Half)( 1.0f), (Half)( 1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)( Half.One), (Half)( Half.One), CrossPlatformMachineEpsilon * (Half)10 }; yield return new object[] { (Half)( 1.18612996f), (Half)( 1.12837917f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (2 / sqrt(pi)) yield return new object[] { (Half)( 1.66514414f), (Half)( 1.41421356f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (sqrt(2)) yield return new object[] { (Half)( 1.71828183f), (Half)( 1.44269504f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (log2(e)) @@ -1544,14 +1544,14 @@ public static IEnumerable Log10P1_TestData() yield return new object[] { (Half)(-2.71828183f), Half.NaN, (Half)0.0f }; // value: -(e) yield return new object[] { (Half)(-1.41421356f), Half.NaN, (Half)0.0f }; // value: -(sqrt(2)) yield return new object[] { Half.NaN, Half.NaN, (Half)0.0f }; - yield return new object[] { (Half)(-1.0f), Half.NegativeInfinity, (Half)0.0f }; + yield return new object[] { (Half)(-Half.One), Half.NegativeInfinity, (Half)0.0f }; yield return new object[] { (Half)(-0.998086986f), (Half)(-2.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(e) yield return new object[] { (Half)(-0.995017872f), (Half)(-2.30258509f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(ln(10)) yield return new object[] { (Half)(-0.973133959f), (Half)(-1.57079633f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(pi / 2) yield return new object[] { (Half)(-0.963916807f), (Half)(-1.44269504f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(log2(e)) yield return new object[] { (Half)(-0.961471115f), (Half)(-1.41421356f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(sqrt(2)) yield return new object[] { (Half)(-0.925591794f), (Half)(-1.12837917f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(2 / sqrt(pi)) - yield return new object[] { (Half)(-0.9f), (Half)(-1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)(-0.9f), (Half)(-Half.One), CrossPlatformMachineEpsilon * (Half)10 }; yield return new object[] { (Half)(-0.836091364f), (Half)(-0.785398163f), CrossPlatformMachineEpsilon }; // expected: -(pi / 4) yield return new object[] { (Half)(-0.803712240f), (Half)(-0.707106781f), CrossPlatformMachineEpsilon }; // expected: -(1 / sqrt(2)) yield return new object[] { (Half)(-0.797300434f), (Half)(-0.693147181f), CrossPlatformMachineEpsilon }; // expected: -(ln(2)) @@ -1566,7 +1566,7 @@ public static IEnumerable Log10P1_TestData() yield return new object[] { (Half)( 3.93340967f), (Half)( 0.693147181f), CrossPlatformMachineEpsilon }; // expected: (ln(2)) yield return new object[] { (Half)( 4.09456117f), (Half)( 0.707106781f), CrossPlatformMachineEpsilon }; // expected: (1 / sqrt(2)) yield return new object[] { (Half)( 5.10095980f), (Half)( 0.785398163f), CrossPlatformMachineEpsilon }; // expected: (pi / 4) - yield return new object[] { (Half)( 9.0f), (Half)( 1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)( 9.0f), (Half)( Half.One), CrossPlatformMachineEpsilon * (Half)10 }; yield return new object[] { (Half)( 12.4393779f), (Half)( 1.12837917f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (2 / sqrt(pi)) yield return new object[] { (Half)( 24.9545535f), (Half)( 1.41421356f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (sqrt(2)) yield return new object[] { (Half)( 26.7137338f), (Half)( 1.44269504f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (log2(e)) @@ -1583,5 +1583,181 @@ public static void Log10P1Test(Half value, Half expectedResult, Half allowedVari { AssertExtensions.Equal(expectedResult, Half.Log10P1(value), allowedVariance); } + + public static IEnumerable Hypot_TestData() + { + yield return new object[] { Half.NaN, Half.NaN, Half.NaN, Half.Zero }; + yield return new object[] { Half.NaN, Half.Zero, Half.NaN, Half.Zero }; + yield return new object[] { Half.NaN, Half.One, Half.NaN, Half.Zero }; + yield return new object[] { Half.NaN, Half.E, Half.NaN, Half.Zero }; + yield return new object[] { Half.NaN, (Half)10.0f, Half.NaN, Half.Zero }; + yield return new object[] { Half.Zero, Half.Zero, Half.Zero, Half.Zero }; + yield return new object[] { Half.Zero, Half.One, Half.One, Half.Zero }; + yield return new object[] { Half.Zero, (Half)1.57079633f, (Half)1.57079633f, Half.Zero }; + yield return new object[] { Half.Zero, (Half)2.0f, (Half)2.0f, Half.Zero }; + yield return new object[] { Half.Zero, Half.E, Half.E, Half.Zero }; + yield return new object[] { Half.Zero, (Half)3.0f, (Half)3.0f, Half.Zero }; + yield return new object[] { Half.Zero, (Half)10.0f, (Half)10.0f, Half.Zero }; + yield return new object[] { Half.One, Half.One, (Half)1.41421356f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { Half.E, (Half)0.318309886f, (Half)2.73685536f, CrossPlatformMachineEpsilon * (Half)10 }; // x: (e) y: (1 / pi) + yield return new object[] { Half.E, (Half)0.434294482f, (Half)2.75275640f, CrossPlatformMachineEpsilon * (Half)10 }; // x: (e) y: (log10(e)) + yield return new object[] { Half.E, (Half)0.636619772f, (Half)2.79183467f, CrossPlatformMachineEpsilon * (Half)10 }; // x: (e) y: (2 / pi) + yield return new object[] { Half.E, (Half)0.693147181f, (Half)2.80526454f, CrossPlatformMachineEpsilon * (Half)10 }; // x: (e) y: (ln(2)) + yield return new object[] { Half.E, (Half)0.707106781f, (Half)2.80874636f, CrossPlatformMachineEpsilon * (Half)10 }; // x: (e) y: (1 / sqrt(2)) + yield return new object[] { Half.E, (Half)0.785398163f, (Half)2.82947104f, CrossPlatformMachineEpsilon * (Half)10 }; // x: (e) y: (pi / 4) + yield return new object[] { Half.E, Half.One, (Half)2.89638673f, CrossPlatformMachineEpsilon * (Half)10 }; // x: (e) + yield return new object[] { Half.E, (Half)1.12837917f, (Half)2.94317781f, CrossPlatformMachineEpsilon * (Half)10 }; // x: (e) y: (2 / sqrt(pi)) + yield return new object[] { Half.E, (Half)1.41421356f, (Half)3.06415667f, CrossPlatformMachineEpsilon * (Half)10 }; // x: (e) y: (sqrt(2)) + yield return new object[] { Half.E, (Half)1.44269504f, (Half)3.07740558f, CrossPlatformMachineEpsilon * (Half)10 }; // x: (e) y: (log2(e)) + yield return new object[] { Half.E, (Half)1.57079633f, (Half)3.13949951f, CrossPlatformMachineEpsilon * (Half)10 }; // x: (e) y: (pi / 2) + yield return new object[] { Half.E, (Half)2.30258509f, (Half)3.56243656f, CrossPlatformMachineEpsilon * (Half)10 }; // x: (e) y: (ln(10)) + yield return new object[] { Half.E, Half.E, (Half)3.84423103f, CrossPlatformMachineEpsilon * (Half)10 }; // x: (e) y: (e) + yield return new object[] { Half.E, (Half)3.14159265f, (Half)4.15435440f, CrossPlatformMachineEpsilon * (Half)10 }; // x: (e) y: (pi) + yield return new object[] { (Half)10.0f, (Half)0.318309886f, (Half)10.0050648f, CrossPlatformMachineEpsilon * (Half)100 }; // y: (1 / pi) + yield return new object[] { (Half)10.0f, (Half)0.434294482f, (Half)10.0094261f, CrossPlatformMachineEpsilon * (Half)100 }; // y: (log10(e)) + yield return new object[] { (Half)10.0f, (Half)0.636619772f, (Half)10.0202437f, CrossPlatformMachineEpsilon * (Half)100 }; // y: (2 / pi) + yield return new object[] { (Half)10.0f, (Half)0.693147181f, (Half)10.0239939f, CrossPlatformMachineEpsilon * (Half)100 }; // y: (ln(2)) + yield return new object[] { (Half)10.0f, (Half)0.707106781f, (Half)10.0249688f, CrossPlatformMachineEpsilon * (Half)100 }; // y: (1 / sqrt(2)) + yield return new object[] { (Half)10.0f, (Half)0.785398163f, (Half)10.0307951f, CrossPlatformMachineEpsilon * (Half)100 }; // y: (pi / 4) + yield return new object[] { (Half)10.0f, Half.One, (Half)10.0498756f, CrossPlatformMachineEpsilon * (Half)100 }; // + yield return new object[] { (Half)10.0f, (Half)1.12837917f, (Half)10.0634606f, CrossPlatformMachineEpsilon * (Half)100 }; // y: (2 / sqrt(pi)) + yield return new object[] { (Half)10.0f, (Half)1.41421356f, (Half)10.0995049f, CrossPlatformMachineEpsilon * (Half)100 }; // y: (sqrt(2)) + yield return new object[] { (Half)10.0f, (Half)1.44269504f, (Half)10.1035325f, CrossPlatformMachineEpsilon * (Half)100 }; // y: (log2(e)) + yield return new object[] { (Half)10.0f, (Half)1.57079633f, (Half)10.1226183f, CrossPlatformMachineEpsilon * (Half)100 }; // y: (pi / 2) + yield return new object[] { (Half)10.0f, (Half)2.30258509f, (Half)10.2616713f, CrossPlatformMachineEpsilon * (Half)100 }; // y: (ln(10)) + yield return new object[] { (Half)10.0f, Half.E, (Half)10.3628691f, CrossPlatformMachineEpsilon * (Half)100 }; // y: (e) + yield return new object[] { (Half)10.0f, (Half)3.14159265f, (Half)10.4818703f, CrossPlatformMachineEpsilon * (Half)100 }; // y: (pi) + yield return new object[] { Half.PositiveInfinity, Half.NaN, Half.PositiveInfinity, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, Half.Zero, Half.PositiveInfinity, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, Half.One, Half.PositiveInfinity, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, Half.E, Half.PositiveInfinity, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, 10.0f, Half.PositiveInfinity, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, Half.PositiveInfinity, Half.PositiveInfinity, Half.Zero }; + } + + [Theory] + [MemberData(nameof(Hypot_TestData))] + public static void Hypot(float x, float y, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, float.Hypot(-x, -y), allowedVariance); + AssertExtensions.Equal(expectedResult, float.Hypot(-x, +y), allowedVariance); + AssertExtensions.Equal(expectedResult, float.Hypot(+x, -y), allowedVariance); + AssertExtensions.Equal(expectedResult, float.Hypot(+x, +y), allowedVariance); + + AssertExtensions.Equal(expectedResult, float.Hypot(-y, -x), allowedVariance); + AssertExtensions.Equal(expectedResult, float.Hypot(-y, +x), allowedVariance); + AssertExtensions.Equal(expectedResult, float.Hypot(+y, -x), allowedVariance); + AssertExtensions.Equal(expectedResult, float.Hypot(+y, +x), allowedVariance); + } + + public static IEnumerable Root_TestData() + { + yield return new object[] { Half.NegativeInfinity, -5, -Half.Zero, Half.Zero }; + yield return new object[] { Half.NegativeInfinity, -4, Half.NaN, Half.Zero }; + yield return new object[] { Half.NegativeInfinity, -3, -Half.Zero, Half.Zero }; + yield return new object[] { Half.NegativeInfinity, -2, Half.NaN, Half.Zero }; + yield return new object[] { Half.NegativeInfinity, -1, -Half.Zero, Half.Zero }; + yield return new object[] { Half.NegativeInfinity, 0, Half.NaN, Half.Zero }; + yield return new object[] { Half.NegativeInfinity, 1, Half.NegativeInfinity, Half.Zero }; + yield return new object[] { Half.NegativeInfinity, 2, Half.NaN, Half.Zero }; + yield return new object[] { Half.NegativeInfinity, 3, Half.NegativeInfinity, Half.Zero }; + yield return new object[] { Half.NegativeInfinity, 4, Half.NaN, Half.Zero }; + yield return new object[] { Half.NegativeInfinity, 5, Half.NegativeInfinity, Half.Zero }; + yield return new object[] {-Half.E, -5, -(Half)0.81873075f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] {-Half.E, -4, Half.NaN, Half.Zero }; + yield return new object[] {-Half.E, -3, -(Half)0.71653131f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] {-Half.E, -2, Half.NaN, Half.Zero }; + yield return new object[] {-Half.E, -1, -(Half)0.36787944f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] {-Half.E, 0, Half.NaN, Half.Zero }; + yield return new object[] {-Half.E, 1, -Half.E, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] {-Half.E, 2, Half.NaN, Half.Zero }; + yield return new object[] {-Half.E, 3, -(Half)1.39561243f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] {-Half.E, 4, Half.NaN, Half.Zero }; + yield return new object[] {-Half.E, 5, -(Half)1.22140276f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] {-Half.One, -5, -Half.One, Half.Zero }; + yield return new object[] {-Half.One, -4, Half.NaN, Half.Zero }; + yield return new object[] {-Half.One, -3, -Half.One, Half.Zero }; + yield return new object[] {-Half.One, -2, Half.NaN, Half.Zero }; + yield return new object[] {-Half.One, -1, -Half.One, Half.Zero }; + yield return new object[] {-Half.One, 0, Half.NaN, Half.Zero }; + yield return new object[] {-Half.One, 1, -Half.One, Half.Zero }; + yield return new object[] {-Half.One, 2, Half.NaN, Half.Zero }; + yield return new object[] {-Half.One, 3, -Half.One, Half.Zero }; + yield return new object[] {-Half.One, 4, Half.NaN, Half.Zero }; + yield return new object[] {-Half.One, 5, -Half.One, Half.Zero }; + yield return new object[] {-Half.Zero, -5, Half.NegativeInfinity, Half.Zero }; + yield return new object[] {-Half.Zero, -4, Half.PositiveInfinity, Half.Zero }; + yield return new object[] {-Half.Zero, -3, Half.NegativeInfinity, Half.Zero }; + yield return new object[] {-Half.Zero, -2, Half.PositiveInfinity, Half.Zero }; + yield return new object[] {-Half.Zero, -1, Half.NegativeInfinity, Half.Zero }; + yield return new object[] {-Half.Zero, 0, Half.NaN, Half.Zero }; + yield return new object[] {-Half.Zero, 1, -Half.Zero, Half.Zero }; + yield return new object[] {-Half.Zero, 2, Half.Zero, Half.Zero }; + yield return new object[] {-Half.Zero, 3, -Half.Zero, Half.Zero }; + yield return new object[] {-Half.Zero, 4, Half.Zero, Half.Zero }; + yield return new object[] {-Half.Zero, 5, -Half.Zero, Half.Zero }; + yield return new object[] { Half.NaN, -5, Half.NaN, Half.Zero }; + yield return new object[] { Half.NaN, -4, Half.NaN, Half.Zero }; + yield return new object[] { Half.NaN, -3, Half.NaN, Half.Zero }; + yield return new object[] { Half.NaN, -2, Half.NaN, Half.Zero }; + yield return new object[] { Half.NaN, -1, Half.NaN, Half.Zero }; + yield return new object[] { Half.NaN, 0, Half.NaN, Half.Zero }; + yield return new object[] { Half.NaN, 1, Half.NaN, Half.Zero }; + yield return new object[] { Half.NaN, 2, Half.NaN, Half.Zero }; + yield return new object[] { Half.NaN, 3, Half.NaN, Half.Zero }; + yield return new object[] { Half.NaN, 4, Half.NaN, Half.Zero }; + yield return new object[] { Half.NaN, 5, Half.NaN, Half.Zero }; + yield return new object[] { Half.Zero, -5, Half.PositiveInfinity, Half.Zero }; + yield return new object[] { Half.Zero, -4, Half.PositiveInfinity, Half.Zero }; + yield return new object[] { Half.Zero, -3, Half.PositiveInfinity, Half.Zero }; + yield return new object[] { Half.Zero, -2, Half.PositiveInfinity, Half.Zero }; + yield return new object[] { Half.Zero, -1, Half.PositiveInfinity, Half.Zero }; + yield return new object[] { Half.Zero, 0, Half.NaN, Half.Zero }; + yield return new object[] { Half.Zero, 1, Half.Zero, Half.Zero }; + yield return new object[] { Half.Zero, 2, Half.Zero, Half.Zero }; + yield return new object[] { Half.Zero, 3, Half.Zero, Half.Zero }; + yield return new object[] { Half.Zero, 4, Half.Zero, Half.Zero }; + yield return new object[] { Half.Zero, 5, Half.Zero, Half.Zero }; + yield return new object[] { Half.One, -5, Half.One, Half.Zero }; + yield return new object[] { Half.One, -4, Half.One, Half.Zero }; + yield return new object[] { Half.One, -3, Half.One, Half.Zero }; + yield return new object[] { Half.One, -2, Half.One, Half.Zero }; + yield return new object[] { Half.One, -1, Half.One, Half.Zero }; + yield return new object[] { Half.One, 0, Half.NaN, Half.Zero }; + yield return new object[] { Half.One, 1, Half.One, Half.Zero }; + yield return new object[] { Half.One, 2, Half.One, Half.Zero }; + yield return new object[] { Half.One, 3, Half.One, Half.Zero }; + yield return new object[] { Half.One, 4, Half.One, Half.Zero }; + yield return new object[] { Half.One, 5, Half.One, Half.Zero }; + yield return new object[] { Half.E, -5, (Half)0.81873075f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { Half.E, -4, (Half)0.77880078f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { Half.E, -3, (Half)0.71653131f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { Half.E, -2, (Half)0.60653066f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { Half.E, -1, (Half)0.36787944f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { Half.E, 0, Half.NaN, Half.Zero }; + yield return new object[] { Half.E, 1, Half.E, Half.Zero }; + yield return new object[] { Half.E, 2, (Half)1.64872127f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { Half.E, 3, (Half)1.39561243f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { Half.E, 4, (Half)1.28402542f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { Half.E, 5, (Half)1.22140276f, CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { Half.PositiveInfinity, -5, Half.Zero, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, -4, Half.Zero, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, -3, Half.Zero, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, -2, Half.Zero, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, -1, Half.Zero, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, 0, Half.NaN, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, 1, Half.PositiveInfinity, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, 2, Half.PositiveInfinity, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, 3, Half.PositiveInfinity, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, 4, Half.PositiveInfinity, Half.Zero }; + yield return new object[] { Half.PositiveInfinity, 5, Half.PositiveInfinity, Half.Zero }; + } + + [Theory] + [MemberData(nameof(Root_TestData))] + public static void Root(Half x, int n, Half expectedResult, Half allowedVariance) + { + AssertExtensions.Equal(expectedResult, Half.Root(x, n), allowedVariance); + } } } diff --git a/src/libraries/System.Runtime/tests/System/SingleTests.cs b/src/libraries/System.Runtime/tests/System/SingleTests.cs index 5f28d89c2ea..62b00c3152b 100644 --- a/src/libraries/System.Runtime/tests/System/SingleTests.cs +++ b/src/libraries/System.Runtime/tests/System/SingleTests.cs @@ -154,6 +154,67 @@ public static void GetTypeCode_Invoke_ReturnsSingle() Assert.Equal(TypeCode.Single, 0.0f.GetTypeCode()); } + [Theory] + [InlineData(float.NaN, float.NaN, float.NaN, 0.0f)] + [InlineData(float.NaN, 0.0f, float.NaN, 0.0f)] + [InlineData(float.NaN, 1.0f, float.NaN, 0.0f)] + [InlineData(float.NaN, 2.71828183f, float.NaN, 0.0f)] + [InlineData(float.NaN, 10.0f, float.NaN, 0.0f)] + [InlineData(0.0f, 0.0f, 0.0f, 0.0f)] + [InlineData(0.0f, 1.0f, 1.0f, 0.0f)] + [InlineData(0.0f, 1.57079633f, 1.57079633f, 0.0f)] + [InlineData(0.0f, 2.0f, 2.0f, 0.0f)] + [InlineData(0.0f, 2.71828183f, 2.71828183f, 0.0f)] + [InlineData(0.0f, 3.0f, 3.0f, 0.0f)] + [InlineData(0.0f, 10.0f, 10.0f, 0.0f)] + [InlineData(1.0f, 1.0f, 1.41421356f, CrossPlatformMachineEpsilon * 10)] + [InlineData(2.71828183f, 0.318309886f, 2.73685536f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (1 / pi) + [InlineData(2.71828183f, 0.434294482f, 2.75275640f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (log10(e)) + [InlineData(2.71828183f, 0.636619772f, 2.79183467f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (2 / pi) + [InlineData(2.71828183f, 0.693147181f, 2.80526454f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (ln(2)) + [InlineData(2.71828183f, 0.707106781f, 2.80874636f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (1 / sqrt(2)) + [InlineData(2.71828183f, 0.785398163f, 2.82947104f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (pi / 4) + [InlineData(2.71828183f, 1.0f, 2.89638673f, CrossPlatformMachineEpsilon * 10)] // x: (e) + [InlineData(2.71828183f, 1.12837917f, 2.94317781f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (2 / sqrt(pi)) + [InlineData(2.71828183f, 1.41421356f, 3.06415667f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (sqrt(2)) + [InlineData(2.71828183f, 1.44269504f, 3.07740558f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (log2(e)) + [InlineData(2.71828183f, 1.57079633f, 3.13949951f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (pi / 2) + [InlineData(2.71828183f, 2.30258509f, 3.56243656f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (ln(10)) + [InlineData(2.71828183f, 2.71828183f, 3.84423103f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (e) + [InlineData(2.71828183f, 3.14159265f, 4.15435440f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (pi) + [InlineData(10.0f, 0.318309886f, 10.0050648f, CrossPlatformMachineEpsilon * 100)] // y: (1 / pi) + [InlineData(10.0f, 0.434294482f, 10.0094261f, CrossPlatformMachineEpsilon * 100)] // y: (log10(e)) + [InlineData(10.0f, 0.636619772f, 10.0202437f, CrossPlatformMachineEpsilon * 100)] // y: (2 / pi) + [InlineData(10.0f, 0.693147181f, 10.0239939f, CrossPlatformMachineEpsilon * 100)] // y: (ln(2)) + [InlineData(10.0f, 0.707106781f, 10.0249688f, CrossPlatformMachineEpsilon * 100)] // y: (1 / sqrt(2)) + [InlineData(10.0f, 0.785398163f, 10.0307951f, CrossPlatformMachineEpsilon * 100)] // y: (pi / 4) + [InlineData(10.0f, 1.0f, 10.0498756f, CrossPlatformMachineEpsilon * 100)] // + [InlineData(10.0f, 1.12837917f, 10.0634606f, CrossPlatformMachineEpsilon * 100)] // y: (2 / sqrt(pi)) + [InlineData(10.0f, 1.41421356f, 10.0995049f, CrossPlatformMachineEpsilon * 100)] // y: (sqrt(2)) + [InlineData(10.0f, 1.44269504f, 10.1035325f, CrossPlatformMachineEpsilon * 100)] // y: (log2(e)) + [InlineData(10.0f, 1.57079633f, 10.1226183f, CrossPlatformMachineEpsilon * 100)] // y: (pi / 2) + [InlineData(10.0f, 2.30258509f, 10.2616713f, CrossPlatformMachineEpsilon * 100)] // y: (ln(10)) + [InlineData(10.0f, 2.71828183f, 10.3628691f, CrossPlatformMachineEpsilon * 100)] // y: (e) + [InlineData(10.0f, 3.14159265f, 10.4818703f, CrossPlatformMachineEpsilon * 100)] // y: (pi) + [InlineData(float.PositiveInfinity, float.NaN, float.PositiveInfinity, 0.0f)] + [InlineData(float.PositiveInfinity, 0.0f, float.PositiveInfinity, 0.0f)] + [InlineData(float.PositiveInfinity, 1.0f, float.PositiveInfinity, 0.0f)] + [InlineData(float.PositiveInfinity, 2.71828183f, float.PositiveInfinity, 0.0f)] + [InlineData(float.PositiveInfinity, 10.0f, float.PositiveInfinity, 0.0f)] + [InlineData(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Hypot(float x, float y, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, float.Hypot(-x, -y), allowedVariance); + AssertExtensions.Equal(expectedResult, float.Hypot(-x, +y), allowedVariance); + AssertExtensions.Equal(expectedResult, float.Hypot(+x, -y), allowedVariance); + AssertExtensions.Equal(expectedResult, float.Hypot(+x, +y), allowedVariance); + + AssertExtensions.Equal(expectedResult, float.Hypot(-y, -x), allowedVariance); + AssertExtensions.Equal(expectedResult, float.Hypot(-y, +x), allowedVariance); + AssertExtensions.Equal(expectedResult, float.Hypot(+y, -x), allowedVariance); + AssertExtensions.Equal(expectedResult, float.Hypot(+y, +x), allowedVariance); + } + [Theory] [InlineData(float.NegativeInfinity, true)] // Negative Infinity [InlineData(float.MinValue, false)] // Min Negative Normal @@ -498,6 +559,111 @@ public static void PositiveInfinity() Assert.Equal(0x7F800000u, BitConverter.SingleToUInt32Bits(float.PositiveInfinity)); } + [Theory] + [InlineData( float.NegativeInfinity, -5, -0.0f, 0.0f)] + [InlineData( float.NegativeInfinity, -4, float.NaN, 0.0f)] + [InlineData( float.NegativeInfinity, -3, -0.0f, 0.0f)] + [InlineData( float.NegativeInfinity, -2, float.NaN, 0.0f)] + [InlineData( float.NegativeInfinity, -1, -0.0f, 0.0f)] + [InlineData( float.NegativeInfinity, 0, float.NaN, 0.0f)] + [InlineData( float.NegativeInfinity, 1, float.NegativeInfinity, 0.0f)] + [InlineData( float.NegativeInfinity, 2, float.NaN, 0.0f)] + [InlineData( float.NegativeInfinity, 3, float.NegativeInfinity, 0.0f)] + [InlineData( float.NegativeInfinity, 4, float.NaN, 0.0f)] + [InlineData( float.NegativeInfinity, 5, float.NegativeInfinity, 0.0f)] + [InlineData(-2.71828183f, -5, -0.81873075f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-2.71828183f, -4, float.NaN, 0.0f)] + [InlineData(-2.71828183f, -3, -0.71653131f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-2.71828183f, -2, float.NaN, 0.0f)] + [InlineData(-2.71828183f, -1, -0.36787944f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-2.71828183f, 0, float.NaN, 0.0f)] + [InlineData(-2.71828183f, 1, -2.71828183f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-2.71828183f, 2, float.NaN, 0.0f)] + [InlineData(-2.71828183f, 3, -1.39561243f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-2.71828183f, 4, float.NaN, 0.0f)] + [InlineData(-2.71828183f, 5, -1.22140276f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-1.0f, -5, -1.0f, 0.0f)] + [InlineData(-1.0f, -4, float.NaN, 0.0f)] + [InlineData(-1.0f, -3, -1.0f, 0.0f)] + [InlineData(-1.0f, -2, float.NaN, 0.0f)] + [InlineData(-1.0f, -1, -1.0f, 0.0f)] + [InlineData(-1.0f, 0, float.NaN, 0.0f)] + [InlineData(-1.0f, 1, -1.0f, 0.0f)] + [InlineData(-1.0f, 2, float.NaN, 0.0f)] + [InlineData(-1.0f, 3, -1.0f, 0.0f)] + [InlineData(-1.0f, 4, float.NaN, 0.0f)] + [InlineData(-1.0f, 5, -1.0f, 0.0f)] + [InlineData(-0.0f, -5, float.NegativeInfinity, 0.0f)] + [InlineData(-0.0f, -4, float.PositiveInfinity, 0.0f)] + [InlineData(-0.0f, -3, float.NegativeInfinity, 0.0f)] + [InlineData(-0.0f, -2, float.PositiveInfinity, 0.0f)] + [InlineData(-0.0f, -1, float.NegativeInfinity, 0.0f)] + [InlineData(-0.0f, 0, float.NaN, 0.0f)] + [InlineData(-0.0f, 1, -0.0f, 0.0f)] + [InlineData(-0.0f, 2, 0.0f, 0.0f)] + [InlineData(-0.0f, 3, -0.0f, 0.0f)] + [InlineData(-0.0f, 4, 0.0f, 0.0f)] + [InlineData(-0.0f, 5, -0.0f, 0.0f)] + [InlineData( float.NaN, -5, float.NaN, 0.0f)] + [InlineData( float.NaN, -4, float.NaN, 0.0f)] + [InlineData( float.NaN, -3, float.NaN, 0.0f)] + [InlineData( float.NaN, -2, float.NaN, 0.0f)] + [InlineData( float.NaN, -1, float.NaN, 0.0f)] + [InlineData( float.NaN, 0, float.NaN, 0.0f)] + [InlineData( float.NaN, 1, float.NaN, 0.0f)] + [InlineData( float.NaN, 2, float.NaN, 0.0f)] + [InlineData( float.NaN, 3, float.NaN, 0.0f)] + [InlineData( float.NaN, 4, float.NaN, 0.0f)] + [InlineData( float.NaN, 5, float.NaN, 0.0f)] + [InlineData( 0.0f, -5, float.PositiveInfinity, 0.0f)] + [InlineData( 0.0f, -4, float.PositiveInfinity, 0.0f)] + [InlineData( 0.0f, -3, float.PositiveInfinity, 0.0f)] + [InlineData( 0.0f, -2, float.PositiveInfinity, 0.0f)] + [InlineData( 0.0f, -1, float.PositiveInfinity, 0.0f)] + [InlineData( 0.0f, 0, float.NaN, 0.0f)] + [InlineData( 0.0f, 1, 0.0f, 0.0f)] + [InlineData( 0.0f, 2, 0.0f, 0.0f)] + [InlineData( 0.0f, 3, 0.0f, 0.0f)] + [InlineData( 0.0f, 4, 0.0f, 0.0f)] + [InlineData( 0.0f, 5, 0.0f, 0.0f)] + [InlineData( 1.0f, -5, 1.0f, 0.0f)] + [InlineData( 1.0f, -4, 1.0f, 0.0f)] + [InlineData( 1.0f, -3, 1.0f, 0.0f)] + [InlineData( 1.0f, -2, 1.0f, 0.0f)] + [InlineData( 1.0f, -1, 1.0f, 0.0f)] + [InlineData( 1.0f, 0, float.NaN, 0.0f)] + [InlineData( 1.0f, 1, 1.0f, 0.0f)] + [InlineData( 1.0f, 2, 1.0f, 0.0f)] + [InlineData( 1.0f, 3, 1.0f, 0.0f)] + [InlineData( 1.0f, 4, 1.0f, 0.0f)] + [InlineData( 1.0f, 5, 1.0f, 0.0f)] + [InlineData( 2.71828183f, -5, 0.81873075f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.71828183f, -4, 0.77880078f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.71828183f, -3, 0.71653131f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.71828183f, -2, 0.60653066f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.71828183f, -1, 0.36787944f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.71828183f, 0, float.NaN, 0.0f)] + [InlineData( 2.71828183f, 1, 2.71828183f, 0.0f)] + [InlineData( 2.71828183f, 2, 1.64872127f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.71828183f, 3, 1.39561243f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.71828183f, 4, 1.28402542f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.71828183f, 5, 1.22140276f, CrossPlatformMachineEpsilon * 10)] + [InlineData( float.PositiveInfinity, -5, 0.0f, 0.0f)] + [InlineData( float.PositiveInfinity, -4, 0.0f, 0.0f)] + [InlineData( float.PositiveInfinity, -3, 0.0f, 0.0f)] + [InlineData( float.PositiveInfinity, -2, 0.0f, 0.0f)] + [InlineData( float.PositiveInfinity, -1, 0.0f, 0.0f)] + [InlineData( float.PositiveInfinity, 0, float.NaN, 0.0f)] + [InlineData( float.PositiveInfinity, 1, float.PositiveInfinity, 0.0f)] + [InlineData( float.PositiveInfinity, 2, float.PositiveInfinity, 0.0f)] + [InlineData( float.PositiveInfinity, 3, float.PositiveInfinity, 0.0f)] + [InlineData( float.PositiveInfinity, 4, float.PositiveInfinity, 0.0f)] + [InlineData( float.PositiveInfinity, 5, float.PositiveInfinity, 0.0f)] + public static void Root(float x, int n, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, float.Root(x, n), allowedVariance); + } + public static IEnumerable ToString_TestData() { yield return new object[] { -4567.0f, "G", null, "-4567" }; -- GitLab