Exposing IRootFunctions.Hypot and IRootFunctions.Root (#71010)
authorTanner Gooding <tagoo@outlook.com>
Mon, 20 Jun 2022 23:14:52 +0000 (16:14 -0700)
committerGitHub <noreply@github.com>
Mon, 20 Jun 2022 23:14:52 +0000 (16:14 -0700)
* Exposing IRootFunctions.Hypot and IRootFunctions.Root

* Adding tests for IRootFunctions.Hypot and IRootFunctions.Root

12 files changed:
THIRD-PARTY-NOTICES.TXT
src/libraries/System.Private.CoreLib/src/System/Double.cs
src/libraries/System.Private.CoreLib/src/System/Half.cs
src/libraries/System.Private.CoreLib/src/System/Numerics/IRootFunctions.cs
src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs
src/libraries/System.Private.CoreLib/src/System/Single.cs
src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs
src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/NFloatTests.cs
src/libraries/System.Runtime/ref/System.Runtime.cs
src/libraries/System.Runtime/tests/System/DoubleTests.cs
src/libraries/System.Runtime/tests/System/HalfTests.cs
src/libraries/System.Runtime/tests/System/SingleTests.cs

index bfbc03e..83f7a5a 100644 (file)
@@ -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.
index aee762b..3ad8e88 100644 (file)
@@ -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 @@ namespace System
         public static double Clamp(double value, double min, double max) => Math.Clamp(value, min, max);
 
         /// <inheritdoc cref="INumber{TSelf}.CopySign(TSelf, TSelf)" />
-        public static double CopySign(double x, double y) => Math.CopySign(x, y);
+        public static double CopySign(double value, double sign) => Math.CopySign(value, sign);
 
         /// <inheritdoc cref="INumber{TSelf}.Max(TSelf, TSelf)" />
         public static double Max(double x, double y) => Math.Max(x, y);
@@ -1353,15 +1357,289 @@ namespace System
         /// <inheritdoc cref="IRootFunctions{TSelf}.Cbrt(TSelf)" />
         public static double Cbrt(double x) => Math.Cbrt(x);
 
-        // /// <inheritdoc cref="IRootFunctions{TSelf}.Hypot(TSelf, TSelf)" />
-        // public static double Hypot(double x, double y) => Math.Hypot(x, y);
+        /// <inheritdoc cref="IRootFunctions{TSelf}.Hypot(TSelf, TSelf)" />
+        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;
+        }
+
+        /// <inheritdoc cref="IRootFunctions{TSelf}.Root(TSelf, int)" />
+        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;
+            }
+        }
 
         /// <inheritdoc cref="IRootFunctions{TSelf}.Sqrt(TSelf)" />
         public static double Sqrt(double x) => Math.Sqrt(x);
 
-        // /// <inheritdoc cref="IRootFunctions{TSelf}.Root(TSelf, TSelf)" />
-        // public static double Root(double x, double n) => Math.Root(x, n);
-
         //
         // ISignedNumber
         //
index 7e18eac..2dde194 100644 (file)
@@ -1359,7 +1359,7 @@ namespace System
         public static Half Clamp(Half value, Half min, Half max) => (Half)Math.Clamp((float)value, (float)min, (float)max);
 
         /// <inheritdoc cref="INumber{TSelf}.CopySign(TSelf, TSelf)" />
-        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);
 
         /// <inheritdoc cref="INumber{TSelf}.Max(TSelf, TSelf)" />
         public static Half Max(Half x, Half y) => (Half)MathF.Max((float)x, (float)y);
@@ -1788,15 +1788,15 @@ namespace System
         /// <inheritdoc cref="IRootFunctions{TSelf}.Cbrt(TSelf)" />
         public static Half Cbrt(Half x) => (Half)MathF.Cbrt((float)x);
 
-        // /// <inheritdoc cref="IRootFunctions{TSelf}.Hypot(TSelf, TSelf)" />
-        // public static Half Hypot(Half x, Half y) => (Half)MathF.Hypot((float)x, (float)y);
+        /// <inheritdoc cref="IRootFunctions{TSelf}.Hypot(TSelf, TSelf)" />
+        public static Half Hypot(Half x, Half y) => (Half)float.Hypot((float)x, (float)y);
+
+        /// <inheritdoc cref="IRootFunctions{TSelf}.Root(TSelf, int)" />
+        public static Half Root(Half x, int n) => (Half)float.Root((float)x, n);
 
         /// <inheritdoc cref="IRootFunctions{TSelf}.Sqrt(TSelf)" />
         public static Half Sqrt(Half x) => (Half)MathF.Sqrt((float)x);
 
-        // /// <inheritdoc cref="IRootFunctions{TSelf}.Root(TSelf, TSelf)" />
-        // public static Half Root(Half x, Half n) => (Half)MathF.Root((float)x, (float)n);
-
         //
         // ISignedNumber
         //
index f4215cd..b7ba1d5 100644 (file)
@@ -13,13 +13,21 @@ namespace System.Numerics
         /// <returns>The cube-root of <paramref name="x" />.</returns>
         static abstract TSelf Cbrt(TSelf x);
 
+        /// <summary>Computes the hypotenuse given two values representing the lengths of the shorter sides in a right-angled triangle.</summary>
+        /// <param name="x">The value to square and add to <paramref name="y" />.</param>
+        /// <param name="y">The value to square and add to <paramref name="x" />.</param>
+        /// <returns>The square root of <paramref name="x" />-squared plus <paramref name="y" />-squared.</returns>
+        static abstract TSelf Hypot(TSelf x, TSelf y);
+
+        /// <summary>Computes the n-th root of a value.</summary>
+        /// <param name="x">The value whose <paramref name="n" />-th root is to be computed.</param>
+        /// <param name="n">The degree of the root to be computed.</param>
+        /// <returns>The <paramref name="n" />-th root of <paramref name="x" />.</returns>
+        static abstract TSelf Root(TSelf x, int n);
+
         /// <summary>Computes the square-root of a value.</summary>
         /// <param name="x">The value whose square-root is to be computed.</param>
         /// <returns>The square-root of <paramref name="x" />.</returns>
         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);
     }
 }
index 1366ebf..b3f4213 100644 (file)
@@ -1213,7 +1213,7 @@ namespace System.Runtime.InteropServices
         public static NFloat Clamp(NFloat value, NFloat min, NFloat max) => new NFloat(NativeType.Clamp(value._value, min._value, max._value));
 
         /// <inheritdoc cref="INumber{TSelf}.CopySign(TSelf, TSelf)" />
-        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));
 
         /// <inheritdoc cref="INumber{TSelf}.Max(TSelf, TSelf)" />
         public static NFloat Max(NFloat x, NFloat y) => new NFloat(NativeType.Max(x._value, y._value));
@@ -1700,15 +1700,15 @@ namespace System.Runtime.InteropServices
         /// <inheritdoc cref="IRootFunctions{TSelf}.Cbrt(TSelf)" />
         public static NFloat Cbrt(NFloat x) => new NFloat(NativeType.Cbrt(x._value));
 
-        // /// <inheritdoc cref="IRootFunctions{TSelf}.Hypot(TSelf, TSelf)" />
-        // public static NFloat Hypot(NFloat x, NFloat y) => new NFloat(NativeType.Hypot(x._value, y._value));
+        /// <inheritdoc cref="IRootFunctions{TSelf}.Hypot(TSelf, TSelf)" />
+        public static NFloat Hypot(NFloat x, NFloat y) => new NFloat(NativeType.Hypot(x._value, y._value));
+
+        /// <inheritdoc cref="IRootFunctions{TSelf}.Root(TSelf, int)" />
+        public static NFloat Root(NFloat x, int n) => new NFloat(NativeType.Root(x._value, n));
 
         /// <inheritdoc cref="IRootFunctions{TSelf}.Sqrt(TSelf)" />
         public static NFloat Sqrt(NFloat x) => new NFloat(NativeType.Sqrt(x._value));
 
-        // /// <inheritdoc cref="IRootFunctions{TSelf}.Root(TSelf, TSelf)" />
-        // public static NFloat Root(NFloat x, NFloat n) => new NFloat(NativeType.Root(x._value, n._value));
-
         //
         // ISignedNumber
         //
index 9a9b32d..2d45346 100644 (file)
@@ -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 @@ namespace System
         public static float Clamp(float value, float min, float max) => Math.Clamp(value, min, max);
 
         /// <inheritdoc cref="INumber{TSelf}.CopySign(TSelf, TSelf)" />
-        public static float CopySign(float x, float y) => MathF.CopySign(x, y);
+        public static float CopySign(float value, float sign) => MathF.CopySign(value, sign);
 
         /// <inheritdoc cref="INumber{TSelf}.Max(TSelf, TSelf)" />
         public static float Max(float x, float y) => MathF.Max(x, y);
@@ -1336,15 +1337,186 @@ namespace System
         /// <inheritdoc cref="IRootFunctions{TSelf}.Cbrt(TSelf)" />
         public static float Cbrt(float x) => MathF.Cbrt(x);
 
-        // /// <inheritdoc cref="IRootFunctions{TSelf}.Hypot(TSelf, TSelf)" />
-        // public static float Hypot(float x, float y) => MathF.Hypot(x, y);
+        /// <inheritdoc cref="IRootFunctions{TSelf}.Hypot(TSelf, TSelf)" />
+        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;
+        }
+
+        /// <inheritdoc cref="IRootFunctions{TSelf}.Root(TSelf, int)" />
+        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;
+            }
+        }
 
         /// <inheritdoc cref="IRootFunctions{TSelf}.Sqrt(TSelf)" />
         public static float Sqrt(float x) => MathF.Sqrt(x);
 
-        // /// <inheritdoc cref="IRootFunctions{TSelf}.Root(TSelf, TSelf)" />
-        // public static float Root(float x, float n) => MathF.Root(x, n);
-
         //
         // ISignedNumber
         //
index fe4bcd0..75eca17 100644 (file)
@@ -850,7 +850,7 @@ namespace System.Runtime.InteropServices
         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 @@ namespace System.Runtime.InteropServices
         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 @@ namespace System.Runtime.InteropServices
         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; }
index cd3a5d1..fb12b52 100644 (file)
@@ -1440,6 +1440,172 @@ namespace System.Runtime.InteropServices.Tests
             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 @@ namespace System.Runtime.InteropServices.Tests
         {
             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);
+        }
     }
 }
index 6128d31..a26dbe1 100644 (file)
@@ -2127,7 +2127,7 @@ namespace System
         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 @@ namespace System
         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 @@ namespace System
         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 @@ namespace System
         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 @@ namespace System
         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 @@ namespace System
         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 @@ namespace System
         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 @@ namespace System
         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 @@ namespace System
         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 @@ namespace System.Numerics
     public partial interface IRootFunctions<TSelf> where TSelf : System.Numerics.IRootFunctions<TSelf>, System.Numerics.INumberBase<TSelf>
     {
         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<TSelf, TResult> where TSelf : System.Numerics.IShiftOperators<TSelf, TResult>
index ad3b096..d849aac 100644 (file)
@@ -157,6 +157,67 @@ namespace System.Tests
         }
 
         [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
         [InlineData(-2.2250738585072014E-308, false)]   // Max Negative Normal
@@ -558,6 +619,111 @@ namespace System.Tests
             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<object[]> ToString_TestData()
         {
             yield return new object[] { -4567.0, "G", null, "-4567" };
index 9970f29..994536e 100644 (file)
@@ -1121,8 +1121,8 @@ namespace System.Tests
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
 
         public static IEnumerable<object[]> 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 @@ namespace System.Tests
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
 
         public static IEnumerable<object[]> 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 @@ namespace System.Tests
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
 
         public static IEnumerable<object[]> 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 @@ namespace System.Tests
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
         {
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
             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 @@ namespace System.Tests
         {
             AssertExtensions.Equal(expectedResult, Half.Log10P1(value), allowedVariance);
         }
+
+        public static IEnumerable<object[]> 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<object[]> 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);
+        }
     }
 }
index 5f28d89..62b00c3 100644 (file)
@@ -155,6 +155,67 @@ namespace System.Tests
         }
 
         [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
         [InlineData(-1.17549435E-38f, false)]           // Max Negative Normal
@@ -498,6 +559,111 @@ namespace System.Tests
             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<object[]> ToString_TestData()
         {
             yield return new object[] { -4567.0f, "G", null, "-4567" };