未验证 提交 715c71ae 编写于 作者: T Tanner Gooding 提交者: GitHub

Exposing IRootFunctions.Hypot and IRootFunctions.Root (#71010)

* Exposing IRootFunctions.Hypot and IRootFunctions.Root

* Adding tests for IRootFunctions.Hypot and IRootFunctions.Root
上级 19fcc316
......@@ -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.
......@@ -12,6 +12,7 @@
===========================================================*/
using System.Buffers.Binary;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Numerics;
......@@ -106,6 +107,9 @@ namespace System
internal const ulong MinTrailingSignificand = 0x0000_0000_0000_0000;
internal const ulong MaxTrailingSignificand = 0x000F_FFFF_FFFF_FFFF;
internal const int TrailingSignificandLength = 52;
internal const int SignificandLength = TrailingSignificandLength + 1;
internal ushort BiasedExponent
{
get
......@@ -917,7 +921,7 @@ bool IFloatingPoint<double>.TryWriteSignificandLittleEndian(Span<byte> destinati
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 @@ private static bool TryConvertTo<TOther>(double value, [NotNullWhen(true)] out T
/// <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
//
......
......@@ -1359,7 +1359,7 @@ bool IFloatingPoint<Half>.TryWriteSignificandLittleEndian(Span<byte> destination
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 @@ private static bool TryConvertTo<TOther>(Half value, [NotNullWhen(true)] out TOt
/// <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
//
......
......@@ -13,13 +13,21 @@ public interface IRootFunctions<TSelf>
/// <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);
}
}
......@@ -1213,7 +1213,7 @@ bool IFloatingPoint<NFloat>.TryWriteSignificandLittleEndian(Span<byte> destinati
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 @@ private static bool TryConvertTo<TOther>(NFloat value, [NotNullWhen(true)] out T
/// <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
//
......
......@@ -11,6 +11,7 @@
===========================================================*/
using System.Buffers.Binary;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Numerics;
......@@ -900,7 +901,7 @@ bool IFloatingPoint<float>.TryWriteSignificandLittleEndian(Span<byte> destinatio
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 @@ private static bool TryConvertTo<TOther>(float value, [NotNullWhen(true)] out TO
/// <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
//
......
......@@ -850,7 +850,7 @@ public static unsafe partial class NativeMemory
public static System.Runtime.InteropServices.NFloat Clamp(System.Runtime.InteropServices.NFloat value, System.Runtime.InteropServices.NFloat min, System.Runtime.InteropServices.NFloat max) { throw null; }
public int CompareTo(object? obj) { throw null; }
public int CompareTo(System.Runtime.InteropServices.NFloat other) { throw null; }
public static System.Runtime.InteropServices.NFloat CopySign(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; }
public static System.Runtime.InteropServices.NFloat CopySign(System.Runtime.InteropServices.NFloat value, System.Runtime.InteropServices.NFloat sign) { throw null; }
public static System.Runtime.InteropServices.NFloat Cos(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat Cosh(System.Runtime.InteropServices.NFloat x) { throw null; }
public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; }
......@@ -864,6 +864,7 @@ public static unsafe partial class NativeMemory
public static System.Runtime.InteropServices.NFloat Floor(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat FusedMultiplyAdd(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right, System.Runtime.InteropServices.NFloat addend) { throw null; }
public override int GetHashCode() { throw null; }
public static System.Runtime.InteropServices.NFloat Hypot(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; }
public static System.Runtime.InteropServices.NFloat Ieee754Remainder(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right) { throw null; }
public static int ILogB(System.Runtime.InteropServices.NFloat x) { throw null; }
public static bool IsEvenInteger(System.Runtime.InteropServices.NFloat value) { throw null; }
......@@ -984,6 +985,7 @@ public static unsafe partial class NativeMemory
public static System.Runtime.InteropServices.NFloat Pow(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; }
public static System.Runtime.InteropServices.NFloat ReciprocalEstimate(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat ReciprocalSqrtEstimate(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat Root(System.Runtime.InteropServices.NFloat x, int n) { throw null; }
public static System.Runtime.InteropServices.NFloat Round(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat Round(System.Runtime.InteropServices.NFloat x, int digits) { throw null; }
public static System.Runtime.InteropServices.NFloat Round(System.Runtime.InteropServices.NFloat x, int digits, System.MidpointRounding mode) { throw null; }
......
......@@ -2127,7 +2127,7 @@ public partial class DivideByZeroException : System.ArithmeticException
public static double Clamp(double value, double min, double max) { throw null; }
public int CompareTo(double value) { throw null; }
public int CompareTo(object? value) { throw null; }
public static double CopySign(double x, double y) { throw null; }
public static double CopySign(double value, double sign) { throw null; }
public static double Cos(double x) { throw null; }
public static double Cosh(double x) { throw null; }
public bool Equals(double obj) { throw null; }
......@@ -2142,6 +2142,7 @@ public partial class DivideByZeroException : System.ArithmeticException
public static double FusedMultiplyAdd(double left, double right, double addend) { throw null; }
public override int GetHashCode() { throw null; }
public System.TypeCode GetTypeCode() { throw null; }
public static double Hypot(double x, double y) { throw null; }
public static double Ieee754Remainder(double left, double right) { throw null; }
public static int ILogB(double x) { throw null; }
public static bool IsEvenInteger(double value) { throw null; }
......@@ -2188,6 +2189,7 @@ public partial class DivideByZeroException : System.ArithmeticException
public static double Pow(double x, double y) { throw null; }
public static double ReciprocalEstimate(double x) { throw null; }
public static double ReciprocalSqrtEstimate(double x) { throw null; }
public static double Root(double x, int n) { throw null; }
public static double Round(double x) { throw null; }
public static double Round(double x, int digits) { throw null; }
public static double Round(double x, int digits, System.MidpointRounding mode) { throw null; }
......@@ -2748,7 +2750,7 @@ public partial class GopherStyleUriParser : System.UriParser
public static System.Half Clamp(System.Half value, System.Half min, System.Half max) { throw null; }
public int CompareTo(System.Half other) { throw null; }
public int CompareTo(object? obj) { throw null; }
public static System.Half CopySign(System.Half x, System.Half y) { throw null; }
public static System.Half CopySign(System.Half value, System.Half sign) { throw null; }
public static System.Half Cos(System.Half x) { throw null; }
public static System.Half Cosh(System.Half x) { throw null; }
public bool Equals(System.Half other) { throw null; }
......@@ -2762,6 +2764,7 @@ public partial class GopherStyleUriParser : System.UriParser
public static System.Half Floor(System.Half x) { throw null; }
public static System.Half FusedMultiplyAdd(System.Half left, System.Half right, System.Half addend) { throw null; }
public override int GetHashCode() { throw null; }
public static System.Half Hypot(System.Half x, System.Half y) { throw null; }
public static System.Half Ieee754Remainder(System.Half left, System.Half right) { throw null; }
public static int ILogB(System.Half x) { throw null; }
public static bool IsEvenInteger(System.Half value) { throw null; }
......@@ -2877,6 +2880,7 @@ public partial class GopherStyleUriParser : System.UriParser
public static System.Half Pow(System.Half x, System.Half y) { throw null; }
public static System.Half ReciprocalEstimate(System.Half x) { throw null; }
public static System.Half ReciprocalSqrtEstimate(System.Half x) { throw null; }
public static System.Half Root(System.Half x, int n) { throw null; }
public static System.Half Round(System.Half x) { throw null; }
public static System.Half Round(System.Half x, int digits) { throw null; }
public static System.Half Round(System.Half x, int digits, System.MidpointRounding mode) { throw null; }
......@@ -4718,7 +4722,7 @@ public sealed partial class SerializableAttribute : System.Attribute
public static float Clamp(float value, float min, float max) { throw null; }
public int CompareTo(object? value) { throw null; }
public int CompareTo(float value) { throw null; }
public static float CopySign(float x, float y) { throw null; }
public static float CopySign(float value, float sign) { throw null; }
public static float Cos(float x) { throw null; }
public static float Cosh(float x) { throw null; }
public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; }
......@@ -4733,6 +4737,7 @@ public sealed partial class SerializableAttribute : System.Attribute
public static float FusedMultiplyAdd(float left, float right, float addend) { throw null; }
public override int GetHashCode() { throw null; }
public System.TypeCode GetTypeCode() { throw null; }
public static float Hypot(float x, float y) { throw null; }
public static float Ieee754Remainder(float left, float right) { throw null; }
public static int ILogB(float x) { throw null; }
public static bool IsEvenInteger(float value) { throw null; }
......@@ -4779,6 +4784,7 @@ public sealed partial class SerializableAttribute : System.Attribute
public static float Pow(float x, float y) { throw null; }
public static float ReciprocalEstimate(float x) { throw null; }
public static float ReciprocalSqrtEstimate(float x) { throw null; }
public static float Root(float x, int n) { throw null; }
public static float Round(float x) { throw null; }
public static float Round(float x, int digits) { throw null; }
public static float Round(float x, int digits, System.MidpointRounding mode) { throw null; }
......@@ -10516,6 +10522,8 @@ public partial interface IPowerFunctions<TSelf> where TSelf : System.Numerics.IP
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>
......@@ -156,6 +156,67 @@ public static void GetTypeCode_Invoke_ReturnsDouble()
Assert.Equal(TypeCode.Double, 0.0.GetTypeCode());
}
[Theory]
[InlineData(double.NaN, double.NaN, double.NaN, 0.0)]
[InlineData(double.NaN, 0.0f, double.NaN, 0.0)]
[InlineData(double.NaN, 1.0f, double.NaN, 0.0)]
[InlineData(double.NaN, 2.7182818284590452, double.NaN, 0.0)]
[InlineData(double.NaN, 10.0, double.NaN, 0.0)]
[InlineData(0.0, 0.0, 0.0, 0.0)]
[InlineData(0.0, 1.0, 1.0, 0.0)]
[InlineData(0.0, 1.5707963267948966, 1.5707963267948966, 0.0)]
[InlineData(0.0, 2.0, 2.0, 0.0)]
[InlineData(0.0, 2.7182818284590452, 2.7182818284590452, 0.0)]
[InlineData(0.0, 3.0, 3.0, 0.0)]
[InlineData(0.0, 10.0, 10.0, 0.0)]
[InlineData(1.0, 1.0, 1.4142135623730950, CrossPlatformMachineEpsilon * 10)]
[InlineData(2.7182818284590452, 0.31830988618379067, 2.7368553638387594, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (1 / pi)
[InlineData(2.7182818284590452, 0.43429448190325183, 2.7527563996732919, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (log10(e))
[InlineData(2.7182818284590452, 0.63661977236758134, 2.7918346715914253, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (2 / pi)
[InlineData(2.7182818284590452, 0.69314718055994531, 2.8052645352709344, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (ln(2))
[InlineData(2.7182818284590452, 0.70710678118654752, 2.8087463571726533, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (1 / sqrt(2))
[InlineData(2.7182818284590452, 0.78539816339744831, 2.8294710413783590, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (pi / 4)
[InlineData(2.7182818284590452, 1.0, 2.8963867315900082, CrossPlatformMachineEpsilon * 10)] // x: (e)
[InlineData(2.7182818284590452, 1.1283791670955126, 2.9431778138036127, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (2 / sqrt(pi))
[InlineData(2.7182818284590452, 1.4142135623730950, 3.0641566701020120, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (sqrt(2))
[InlineData(2.7182818284590452, 1.4426950408889634, 3.0774055761202907, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (log2(e))
[InlineData(2.7182818284590452, 1.5707963267948966, 3.1394995141268918, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (pi / 2)
[InlineData(2.7182818284590452, 2.3025850929940457, 3.5624365551415857, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (ln(10))
[InlineData(2.7182818284590452, 2.7182818284590452, 3.8442310281591168, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (e)
[InlineData(2.7182818284590452, 3.1415926535897932, 4.1543544023133136, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (pi)
[InlineData(10.0, 0.31830988618379067, 10.005064776584025, CrossPlatformMachineEpsilon * 100)] // y: (1 / pi)
[InlineData(10.0, 0.43429448190325183, 10.009426142242702, CrossPlatformMachineEpsilon * 100)] // y: (log10(e))
[InlineData(10.0, 0.63661977236758134, 10.020243746265325, CrossPlatformMachineEpsilon * 100)] // y: (2 / pi)
[InlineData(10.0, 0.69314718055994531, 10.023993865417028, CrossPlatformMachineEpsilon * 100)] // y: (ln(2))
[InlineData(10.0, 0.70710678118654752, 10.024968827881711, CrossPlatformMachineEpsilon * 100)] // y: (1 / sqrt(2))
[InlineData(10.0, 0.78539816339744831, 10.030795096853892, CrossPlatformMachineEpsilon * 100)] // y: (pi / 4)
[InlineData(10.0, 1.0, 10.049875621120890, CrossPlatformMachineEpsilon * 100)] //
[InlineData(10.0, 1.1283791670955126, 10.063460614755501, CrossPlatformMachineEpsilon * 100)] // y: (2 / sqrt(pi))
[InlineData(10.0, 1.4142135623730950, 10.099504938362078, CrossPlatformMachineEpsilon * 100)] // y: (sqrt(2))
[InlineData(10.0, 1.4426950408889634, 10.103532500121213, CrossPlatformMachineEpsilon * 100)] // y: (log2(e))
[InlineData(10.0, 1.5707963267948966, 10.122618292728040, CrossPlatformMachineEpsilon * 100)] // y: (pi / 2)
[InlineData(10.0, 2.3025850929940457, 10.261671311754163, CrossPlatformMachineEpsilon * 100)] // y: (ln(10))
[InlineData(10.0, 2.7182818284590452, 10.362869105558106, CrossPlatformMachineEpsilon * 100)] // y: (e)
[InlineData(10.0, 3.1415926535897932, 10.481870272097884, CrossPlatformMachineEpsilon * 100)] // y: (pi)
[InlineData(double.PositiveInfinity, double.NaN, double.PositiveInfinity, 0.0)]
[InlineData(double.PositiveInfinity, 0.0, double.PositiveInfinity, 0.0)]
[InlineData(double.PositiveInfinity, 1.0, double.PositiveInfinity, 0.0)]
[InlineData(double.PositiveInfinity, 2.7182818284590452, double.PositiveInfinity, 0.0)]
[InlineData(double.PositiveInfinity, 10.0, double.PositiveInfinity, 0.0)]
[InlineData(double.PositiveInfinity, double.PositiveInfinity, double.PositiveInfinity, 0.0)]
public static void Hypot(double x, double y, double expectedResult, double allowedVariance)
{
AssertExtensions.Equal(expectedResult, double.Hypot(-x, -y), allowedVariance);
AssertExtensions.Equal(expectedResult, double.Hypot(-x, +y), allowedVariance);
AssertExtensions.Equal(expectedResult, double.Hypot(+x, -y), allowedVariance);
AssertExtensions.Equal(expectedResult, double.Hypot(+x, +y), allowedVariance);
AssertExtensions.Equal(expectedResult, double.Hypot(-y, -x), allowedVariance);
AssertExtensions.Equal(expectedResult, double.Hypot(-y, +x), allowedVariance);
AssertExtensions.Equal(expectedResult, double.Hypot(+y, -x), allowedVariance);
AssertExtensions.Equal(expectedResult, double.Hypot(+y, +x), allowedVariance);
}
[Theory]
[InlineData(double.NegativeInfinity, true)] // Negative Infinity
[InlineData(double.MinValue, false)] // Min Negative Normal
......@@ -558,6 +619,111 @@ public static void PositiveInfinity()
Assert.Equal(0x7FF00000_00000000u, BitConverter.DoubleToUInt64Bits(double.PositiveInfinity));
}
[Theory]
[InlineData( double.NegativeInfinity, -5, -0.0, 0.0)]
[InlineData( double.NegativeInfinity, -4, double.NaN, 0.0)]
[InlineData( double.NegativeInfinity, -3, -0.0, 0.0)]
[InlineData( double.NegativeInfinity, -2, double.NaN, 0.0)]
[InlineData( double.NegativeInfinity, -1, -0.0, 0.0)]
[InlineData( double.NegativeInfinity, 0, double.NaN, 0.0)]
[InlineData( double.NegativeInfinity, 1, double.NegativeInfinity, 0.0)]
[InlineData( double.NegativeInfinity, 2, double.NaN, 0.0)]
[InlineData( double.NegativeInfinity, 3, double.NegativeInfinity, 0.0)]
[InlineData( double.NegativeInfinity, 4, double.NaN, 0.0)]
[InlineData( double.NegativeInfinity, 5, double.NegativeInfinity, 0.0)]
[InlineData(-2.7182818284590452, -5, -0.8187307530779819, CrossPlatformMachineEpsilon * 10)]
[InlineData(-2.7182818284590452, -4, double.NaN, 0.0)]
[InlineData(-2.7182818284590452, -3, -0.7165313105737893, CrossPlatformMachineEpsilon * 10)]
[InlineData(-2.7182818284590452, -2, double.NaN, 0.0)]
[InlineData(-2.7182818284590452, -1, -0.3678794411714423, CrossPlatformMachineEpsilon * 10)]
[InlineData(-2.7182818284590452, 0, double.NaN, 0.0)]
[InlineData(-2.7182818284590452, 1, -2.7182818284590452, CrossPlatformMachineEpsilon * 10)]
[InlineData(-2.7182818284590452, 2, double.NaN, 0.0)]
[InlineData(-2.7182818284590452, 3, -1.3956124250860895, CrossPlatformMachineEpsilon * 10)]
[InlineData(-2.7182818284590452, 4, double.NaN, 0.0)]
[InlineData(-2.7182818284590452, 5, -1.2214027581601698, CrossPlatformMachineEpsilon * 10)]
[InlineData(-1.0, -5, -1.0, 0.0)]
[InlineData(-1.0, -4, double.NaN, 0.0)]
[InlineData(-1.0, -3, -1.0, 0.0)]
[InlineData(-1.0, -2, double.NaN, 0.0)]
[InlineData(-1.0, -1, -1.0, 0.0)]
[InlineData(-1.0, 0, double.NaN, 0.0)]
[InlineData(-1.0, 1, -1.0, 0.0)]
[InlineData(-1.0, 2, double.NaN, 0.0)]
[InlineData(-1.0, 3, -1.0, 0.0)]
[InlineData(-1.0, 4, double.NaN, 0.0)]
[InlineData(-1.0, 5, -1.0, 0.0)]
[InlineData(-0.0, -5, double.NegativeInfinity, 0.0)]
[InlineData(-0.0, -4, double.PositiveInfinity, 0.0)]
[InlineData(-0.0, -3, double.NegativeInfinity, 0.0)]
[InlineData(-0.0, -2, double.PositiveInfinity, 0.0)]
[InlineData(-0.0, -1, double.NegativeInfinity, 0.0)]
[InlineData(-0.0, 0, double.NaN, 0.0)]
[InlineData(-0.0, 1, -0.0, 0.0)]
[InlineData(-0.0, 2, 0.0, 0.0)]
[InlineData(-0.0, 3, -0.0, 0.0)]
[InlineData(-0.0, 4, 0.0, 0.0)]
[InlineData(-0.0, 5, -0.0, 0.0)]
[InlineData( double.NaN, -5, double.NaN, 0.0)]
[InlineData( double.NaN, -4, double.NaN, 0.0)]
[InlineData( double.NaN, -3, double.NaN, 0.0)]
[InlineData( double.NaN, -2, double.NaN, 0.0)]
[InlineData( double.NaN, -1, double.NaN, 0.0)]
[InlineData( double.NaN, 0, double.NaN, 0.0)]
[InlineData( double.NaN, 1, double.NaN, 0.0)]
[InlineData( double.NaN, 2, double.NaN, 0.0)]
[InlineData( double.NaN, 3, double.NaN, 0.0)]
[InlineData( double.NaN, 4, double.NaN, 0.0)]
[InlineData( double.NaN, 5, double.NaN, 0.0)]
[InlineData( 0.0, -5, double.PositiveInfinity, 0.0)]
[InlineData( 0.0, -4, double.PositiveInfinity, 0.0)]
[InlineData( 0.0, -3, double.PositiveInfinity, 0.0)]
[InlineData( 0.0, -2, double.PositiveInfinity, 0.0)]
[InlineData( 0.0, -1, double.PositiveInfinity, 0.0)]
[InlineData( 0.0, 0, double.NaN, 0.0)]
[InlineData( 0.0, 1, 0.0, 0.0)]
[InlineData( 0.0, 2, 0.0, 0.0)]
[InlineData( 0.0, 3, 0.0, 0.0)]
[InlineData( 0.0, 4, 0.0, 0.0)]
[InlineData( 0.0, 5, 0.0, 0.0)]
[InlineData( 1.0, -5, 1.0, 0.0)]
[InlineData( 1.0, -4, 1.0, 0.0)]
[InlineData( 1.0, -3, 1.0, 0.0)]
[InlineData( 1.0, -2, 1.0, 0.0)]
[InlineData( 1.0, -1, 1.0, 0.0)]
[InlineData( 1.0, 0, double.NaN, 0.0)]
[InlineData( 1.0, 1, 1.0, 0.0)]
[InlineData( 1.0, 2, 1.0, 0.0)]
[InlineData( 1.0, 3, 1.0, 0.0)]
[InlineData( 1.0, 4, 1.0, 0.0)]
[InlineData( 1.0, 5, 1.0, 0.0)]
[InlineData( 2.7182818284590452, -5, 0.8187307530779819, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.7182818284590452, -4, 0.7788007830714049, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.7182818284590452, -3, 0.7165313105737893, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.7182818284590452, -2, 0.6065306597126334, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.7182818284590452, -1, 0.3678794411714423, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.7182818284590452, 0, double.NaN, 0.0)]
[InlineData( 2.7182818284590452, 1, 2.7182818284590452, 0.0)]
[InlineData( 2.7182818284590452, 2, 1.6487212707001281, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.7182818284590452, 3, 1.3956124250860895, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.7182818284590452, 4, 1.2840254166877415, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.7182818284590452, 5, 1.2214027581601698, CrossPlatformMachineEpsilon * 10)]
[InlineData( double.PositiveInfinity, -5, 0.0f, 0.0)]
[InlineData( double.PositiveInfinity, -4, 0.0f, 0.0)]
[InlineData( double.PositiveInfinity, -3, 0.0f, 0.0)]
[InlineData( double.PositiveInfinity, -2, 0.0f, 0.0)]
[InlineData( double.PositiveInfinity, -1, 0.0f, 0.0)]
[InlineData( double.PositiveInfinity, 0, double.NaN, 0.0)]
[InlineData( double.PositiveInfinity, 1, double.PositiveInfinity, 0.0)]
[InlineData( double.PositiveInfinity, 2, double.PositiveInfinity, 0.0)]
[InlineData( double.PositiveInfinity, 3, double.PositiveInfinity, 0.0)]
[InlineData( double.PositiveInfinity, 4, double.PositiveInfinity, 0.0)]
[InlineData( double.PositiveInfinity, 5, double.PositiveInfinity, 0.0)]
public static void Root(double x, int n, double expectedResult, double allowedVariance)
{
AssertExtensions.Equal(expectedResult, double.Root(x, n), allowedVariance);
}
public static IEnumerable<object[]> ToString_TestData()
{
yield return new object[] { -4567.0, "G", null, "-4567" };
......
......@@ -154,6 +154,67 @@ public static void GetTypeCode_Invoke_ReturnsSingle()
Assert.Equal(TypeCode.Single, 0.0f.GetTypeCode());
}
[Theory]
[InlineData(float.NaN, float.NaN, float.NaN, 0.0f)]
[InlineData(float.NaN, 0.0f, float.NaN, 0.0f)]
[InlineData(float.NaN, 1.0f, float.NaN, 0.0f)]
[InlineData(float.NaN, 2.71828183f, float.NaN, 0.0f)]
[InlineData(float.NaN, 10.0f, float.NaN, 0.0f)]
[InlineData(0.0f, 0.0f, 0.0f, 0.0f)]
[InlineData(0.0f, 1.0f, 1.0f, 0.0f)]
[InlineData(0.0f, 1.57079633f, 1.57079633f, 0.0f)]
[InlineData(0.0f, 2.0f, 2.0f, 0.0f)]
[InlineData(0.0f, 2.71828183f, 2.71828183f, 0.0f)]
[InlineData(0.0f, 3.0f, 3.0f, 0.0f)]
[InlineData(0.0f, 10.0f, 10.0f, 0.0f)]
[InlineData(1.0f, 1.0f, 1.41421356f, CrossPlatformMachineEpsilon * 10)]
[InlineData(2.71828183f, 0.318309886f, 2.73685536f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (1 / pi)
[InlineData(2.71828183f, 0.434294482f, 2.75275640f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (log10(e))
[InlineData(2.71828183f, 0.636619772f, 2.79183467f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (2 / pi)
[InlineData(2.71828183f, 0.693147181f, 2.80526454f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (ln(2))
[InlineData(2.71828183f, 0.707106781f, 2.80874636f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (1 / sqrt(2))
[InlineData(2.71828183f, 0.785398163f, 2.82947104f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (pi / 4)
[InlineData(2.71828183f, 1.0f, 2.89638673f, CrossPlatformMachineEpsilon * 10)] // x: (e)
[InlineData(2.71828183f, 1.12837917f, 2.94317781f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (2 / sqrt(pi))
[InlineData(2.71828183f, 1.41421356f, 3.06415667f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (sqrt(2))
[InlineData(2.71828183f, 1.44269504f, 3.07740558f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (log2(e))
[InlineData(2.71828183f, 1.57079633f, 3.13949951f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (pi / 2)
[InlineData(2.71828183f, 2.30258509f, 3.56243656f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (ln(10))
[InlineData(2.71828183f, 2.71828183f, 3.84423103f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (e)
[InlineData(2.71828183f, 3.14159265f, 4.15435440f, CrossPlatformMachineEpsilon * 10)] // x: (e) y: (pi)
[InlineData(10.0f, 0.318309886f, 10.0050648f, CrossPlatformMachineEpsilon * 100)] // y: (1 / pi)
[InlineData(10.0f, 0.434294482f, 10.0094261f, CrossPlatformMachineEpsilon * 100)] // y: (log10(e))
[InlineData(10.0f, 0.636619772f, 10.0202437f, CrossPlatformMachineEpsilon * 100)] // y: (2 / pi)
[InlineData(10.0f, 0.693147181f, 10.0239939f, CrossPlatformMachineEpsilon * 100)] // y: (ln(2))
[InlineData(10.0f, 0.707106781f, 10.0249688f, CrossPlatformMachineEpsilon * 100)] // y: (1 / sqrt(2))
[InlineData(10.0f, 0.785398163f, 10.0307951f, CrossPlatformMachineEpsilon * 100)] // y: (pi / 4)
[InlineData(10.0f, 1.0f, 10.0498756f, CrossPlatformMachineEpsilon * 100)] //
[InlineData(10.0f, 1.12837917f, 10.0634606f, CrossPlatformMachineEpsilon * 100)] // y: (2 / sqrt(pi))
[InlineData(10.0f, 1.41421356f, 10.0995049f, CrossPlatformMachineEpsilon * 100)] // y: (sqrt(2))
[InlineData(10.0f, 1.44269504f, 10.1035325f, CrossPlatformMachineEpsilon * 100)] // y: (log2(e))
[InlineData(10.0f, 1.57079633f, 10.1226183f, CrossPlatformMachineEpsilon * 100)] // y: (pi / 2)
[InlineData(10.0f, 2.30258509f, 10.2616713f, CrossPlatformMachineEpsilon * 100)] // y: (ln(10))
[InlineData(10.0f, 2.71828183f, 10.3628691f, CrossPlatformMachineEpsilon * 100)] // y: (e)
[InlineData(10.0f, 3.14159265f, 10.4818703f, CrossPlatformMachineEpsilon * 100)] // y: (pi)
[InlineData(float.PositiveInfinity, float.NaN, float.PositiveInfinity, 0.0f)]
[InlineData(float.PositiveInfinity, 0.0f, float.PositiveInfinity, 0.0f)]
[InlineData(float.PositiveInfinity, 1.0f, float.PositiveInfinity, 0.0f)]
[InlineData(float.PositiveInfinity, 2.71828183f, float.PositiveInfinity, 0.0f)]
[InlineData(float.PositiveInfinity, 10.0f, float.PositiveInfinity, 0.0f)]
[InlineData(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity, 0.0f)]
public static void Hypot(float x, float y, float expectedResult, float allowedVariance)
{
AssertExtensions.Equal(expectedResult, float.Hypot(-x, -y), allowedVariance);
AssertExtensions.Equal(expectedResult, float.Hypot(-x, +y), allowedVariance);
AssertExtensions.Equal(expectedResult, float.Hypot(+x, -y), allowedVariance);
AssertExtensions.Equal(expectedResult, float.Hypot(+x, +y), allowedVariance);
AssertExtensions.Equal(expectedResult, float.Hypot(-y, -x), allowedVariance);
AssertExtensions.Equal(expectedResult, float.Hypot(-y, +x), allowedVariance);
AssertExtensions.Equal(expectedResult, float.Hypot(+y, -x), allowedVariance);
AssertExtensions.Equal(expectedResult, float.Hypot(+y, +x), allowedVariance);
}
[Theory]
[InlineData(float.NegativeInfinity, true)] // Negative Infinity
[InlineData(float.MinValue, false)] // Min Negative Normal
......@@ -498,6 +559,111 @@ public static void PositiveInfinity()
Assert.Equal(0x7F800000u, BitConverter.SingleToUInt32Bits(float.PositiveInfinity));
}
[Theory]
[InlineData( float.NegativeInfinity, -5, -0.0f, 0.0f)]
[InlineData( float.NegativeInfinity, -4, float.NaN, 0.0f)]
[InlineData( float.NegativeInfinity, -3, -0.0f, 0.0f)]
[InlineData( float.NegativeInfinity, -2, float.NaN, 0.0f)]
[InlineData( float.NegativeInfinity, -1, -0.0f, 0.0f)]
[InlineData( float.NegativeInfinity, 0, float.NaN, 0.0f)]
[InlineData( float.NegativeInfinity, 1, float.NegativeInfinity, 0.0f)]
[InlineData( float.NegativeInfinity, 2, float.NaN, 0.0f)]
[InlineData( float.NegativeInfinity, 3, float.NegativeInfinity, 0.0f)]
[InlineData( float.NegativeInfinity, 4, float.NaN, 0.0f)]
[InlineData( float.NegativeInfinity, 5, float.NegativeInfinity, 0.0f)]
[InlineData(-2.71828183f, -5, -0.81873075f, CrossPlatformMachineEpsilon * 10)]
[InlineData(-2.71828183f, -4, float.NaN, 0.0f)]
[InlineData(-2.71828183f, -3, -0.71653131f, CrossPlatformMachineEpsilon * 10)]
[InlineData(-2.71828183f, -2, float.NaN, 0.0f)]
[InlineData(-2.71828183f, -1, -0.36787944f, CrossPlatformMachineEpsilon * 10)]
[InlineData(-2.71828183f, 0, float.NaN, 0.0f)]
[InlineData(-2.71828183f, 1, -2.71828183f, CrossPlatformMachineEpsilon * 10)]
[InlineData(-2.71828183f, 2, float.NaN, 0.0f)]
[InlineData(-2.71828183f, 3, -1.39561243f, CrossPlatformMachineEpsilon * 10)]
[InlineData(-2.71828183f, 4, float.NaN, 0.0f)]
[InlineData(-2.71828183f, 5, -1.22140276f, CrossPlatformMachineEpsilon * 10)]
[InlineData(-1.0f, -5, -1.0f, 0.0f)]
[InlineData(-1.0f, -4, float.NaN, 0.0f)]
[InlineData(-1.0f, -3, -1.0f, 0.0f)]
[InlineData(-1.0f, -2, float.NaN, 0.0f)]
[InlineData(-1.0f, -1, -1.0f, 0.0f)]
[InlineData(-1.0f, 0, float.NaN, 0.0f)]
[InlineData(-1.0f, 1, -1.0f, 0.0f)]
[InlineData(-1.0f, 2, float.NaN, 0.0f)]
[InlineData(-1.0f, 3, -1.0f, 0.0f)]
[InlineData(-1.0f, 4, float.NaN, 0.0f)]
[InlineData(-1.0f, 5, -1.0f, 0.0f)]
[InlineData(-0.0f, -5, float.NegativeInfinity, 0.0f)]
[InlineData(-0.0f, -4, float.PositiveInfinity, 0.0f)]
[InlineData(-0.0f, -3, float.NegativeInfinity, 0.0f)]
[InlineData(-0.0f, -2, float.PositiveInfinity, 0.0f)]
[InlineData(-0.0f, -1, float.NegativeInfinity, 0.0f)]
[InlineData(-0.0f, 0, float.NaN, 0.0f)]
[InlineData(-0.0f, 1, -0.0f, 0.0f)]
[InlineData(-0.0f, 2, 0.0f, 0.0f)]
[InlineData(-0.0f, 3, -0.0f, 0.0f)]
[InlineData(-0.0f, 4, 0.0f, 0.0f)]
[InlineData(-0.0f, 5, -0.0f, 0.0f)]
[InlineData( float.NaN, -5, float.NaN, 0.0f)]
[InlineData( float.NaN, -4, float.NaN, 0.0f)]
[InlineData( float.NaN, -3, float.NaN, 0.0f)]
[InlineData( float.NaN, -2, float.NaN, 0.0f)]
[InlineData( float.NaN, -1, float.NaN, 0.0f)]
[InlineData( float.NaN, 0, float.NaN, 0.0f)]
[InlineData( float.NaN, 1, float.NaN, 0.0f)]
[InlineData( float.NaN, 2, float.NaN, 0.0f)]
[InlineData( float.NaN, 3, float.NaN, 0.0f)]
[InlineData( float.NaN, 4, float.NaN, 0.0f)]
[InlineData( float.NaN, 5, float.NaN, 0.0f)]
[InlineData( 0.0f, -5, float.PositiveInfinity, 0.0f)]
[InlineData( 0.0f, -4, float.PositiveInfinity, 0.0f)]
[InlineData( 0.0f, -3, float.PositiveInfinity, 0.0f)]
[InlineData( 0.0f, -2, float.PositiveInfinity, 0.0f)]
[InlineData( 0.0f, -1, float.PositiveInfinity, 0.0f)]
[InlineData( 0.0f, 0, float.NaN, 0.0f)]
[InlineData( 0.0f, 1, 0.0f, 0.0f)]
[InlineData( 0.0f, 2, 0.0f, 0.0f)]
[InlineData( 0.0f, 3, 0.0f, 0.0f)]
[InlineData( 0.0f, 4, 0.0f, 0.0f)]
[InlineData( 0.0f, 5, 0.0f, 0.0f)]
[InlineData( 1.0f, -5, 1.0f, 0.0f)]
[InlineData( 1.0f, -4, 1.0f, 0.0f)]
[InlineData( 1.0f, -3, 1.0f, 0.0f)]
[InlineData( 1.0f, -2, 1.0f, 0.0f)]
[InlineData( 1.0f, -1, 1.0f, 0.0f)]
[InlineData( 1.0f, 0, float.NaN, 0.0f)]
[InlineData( 1.0f, 1, 1.0f, 0.0f)]
[InlineData( 1.0f, 2, 1.0f, 0.0f)]
[InlineData( 1.0f, 3, 1.0f, 0.0f)]
[InlineData( 1.0f, 4, 1.0f, 0.0f)]
[InlineData( 1.0f, 5, 1.0f, 0.0f)]
[InlineData( 2.71828183f, -5, 0.81873075f, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.71828183f, -4, 0.77880078f, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.71828183f, -3, 0.71653131f, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.71828183f, -2, 0.60653066f, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.71828183f, -1, 0.36787944f, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.71828183f, 0, float.NaN, 0.0f)]
[InlineData( 2.71828183f, 1, 2.71828183f, 0.0f)]
[InlineData( 2.71828183f, 2, 1.64872127f, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.71828183f, 3, 1.39561243f, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.71828183f, 4, 1.28402542f, CrossPlatformMachineEpsilon * 10)]
[InlineData( 2.71828183f, 5, 1.22140276f, CrossPlatformMachineEpsilon * 10)]
[InlineData( float.PositiveInfinity, -5, 0.0f, 0.0f)]
[InlineData( float.PositiveInfinity, -4, 0.0f, 0.0f)]
[InlineData( float.PositiveInfinity, -3, 0.0f, 0.0f)]
[InlineData( float.PositiveInfinity, -2, 0.0f, 0.0f)]
[InlineData( float.PositiveInfinity, -1, 0.0f, 0.0f)]
[InlineData( float.PositiveInfinity, 0, float.NaN, 0.0f)]
[InlineData( float.PositiveInfinity, 1, float.PositiveInfinity, 0.0f)]
[InlineData( float.PositiveInfinity, 2, float.PositiveInfinity, 0.0f)]
[InlineData( float.PositiveInfinity, 3, float.PositiveInfinity, 0.0f)]
[InlineData( float.PositiveInfinity, 4, float.PositiveInfinity, 0.0f)]
[InlineData( float.PositiveInfinity, 5, float.PositiveInfinity, 0.0f)]
public static void Root(float x, int n, float expectedResult, float allowedVariance)
{
AssertExtensions.Equal(expectedResult, float.Root(x, n), allowedVariance);
}
public static IEnumerable<object[]> ToString_TestData()
{
yield return new object[] { -4567.0f, "G", null, "-4567" };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册