diff --git a/src/libraries/System.Private.CoreLib/src/System/Double.cs b/src/libraries/System.Private.CoreLib/src/System/Double.cs
index 3ad8e88c640eb4..4bbced51cb342e 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Double.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Double.cs
@@ -1671,47 +1671,310 @@ static double NegativeN(double x, int n)
///
public static double Acos(double x) => Math.Acos(x);
+ ///
+ public static double AcosPi(double x)
+ {
+ return Acos(x) / Pi;
+ }
+
///
public static double Asin(double x) => Math.Asin(x);
+ ///
+ public static double AsinPi(double x)
+ {
+ return Asin(x) / Pi;
+ }
+
///
public static double Atan(double x) => Math.Atan(x);
///
public static double Atan2(double y, double x) => Math.Atan2(y, x);
+ ///
+ public static double Atan2Pi(double y, double x)
+ {
+ return Atan2(y, x) / Pi;
+ }
+
+ ///
+ public static double AtanPi(double x)
+ {
+ return Atan(x) / Pi;
+ }
+
///
public static double Cos(double x) => Math.Cos(x);
+ ///
+ public static double CosPi(double x)
+ {
+ // This code is based on `cospi` 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))
+ {
+ double ax = Abs(x);
+
+ if (ax < 4_503_599_627_370_496.0) // |x| < 2^52
+ {
+ if (ax > 0.25)
+ {
+ long integral = (long)ax;
+
+ double fractional = ax - integral;
+ double sign = long.IsOddInteger(integral) ? -1.0 : +1.0;
+
+ if (fractional <= 0.25)
+ {
+ result = sign;
+
+ if (fractional != 0.00)
+ {
+ result *= CosForIntervalPiBy4(fractional * Pi, 0.0);
+ }
+ }
+ else if (fractional <= 0.50)
+ {
+ if (fractional != 0.50)
+ {
+ result = sign * SinForIntervalPiBy4((0.5 - fractional) * Pi, 0.0);
+ }
+ else
+ {
+ result = 0.0;
+ }
+ }
+ else if (fractional <= 0.75)
+ {
+ result = -sign * SinForIntervalPiBy4((fractional - 0.5) * Pi, 0.0);
+ }
+ else
+ {
+ result = -sign * CosForIntervalPiBy4((1.0 - fractional) * Pi, 0.0);
+ }
+ }
+ else if (ax >= 6.103515625E-05) // |x| >= 2^-14
+ {
+ result = CosForIntervalPiBy4(x * Pi, 0.0);
+ }
+ else if (ax >= 7.450580596923828E-09) // |x| >= 2^-27
+ {
+ result = x * Pi;
+ result = 1.0 - (result * result * 0.5);
+ }
+ else
+ {
+ result = 1.0;
+ }
+ }
+ else if (ax < 9_007_199_254_740_992.0) // |x| < 2^53
+ {
+ // x is an integer
+ long bits = BitConverter.DoubleToInt64Bits(ax);
+ result = long.IsOddInteger(bits) ? -1.0 : +1.0;
+ }
+ else
+ {
+ // x is an even integer
+ result = 1.0;
+ }
+ }
+ else
+ {
+ result = NaN;
+ }
+
+ return result;
+ }
+
///
public static double Sin(double x) => Math.Sin(x);
///
public static (double Sin, double Cos) SinCos(double x) => Math.SinCos(x);
+ ///
+ public static double SinPi(double x)
+ {
+ // This code is based on `sinpi` 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))
+ {
+ double ax = Abs(x);
+
+ if (ax < 4_503_599_627_370_496.0) // |x| < 2^52
+ {
+ if (ax > 0.25)
+ {
+ long integral = (long)ax;
+
+ double fractional = ax - integral;
+ double sign = ((x > 0.0) ? +1.0 : -1.0) * (long.IsOddInteger(integral) ? -1.0 : +1.0);
+
+ if (fractional <= 0.25)
+ {
+ if (fractional != 0.00)
+ {
+ result = sign * SinForIntervalPiBy4(fractional * Pi, 0.0);
+ }
+ else
+ {
+ result = x * 0.0;
+ }
+ }
+ else if (fractional <= 0.50)
+ {
+ result = sign;
+
+ if (fractional != 0.50)
+ {
+ result *= CosForIntervalPiBy4((0.5 - fractional) * Pi, 0.0);
+ }
+ }
+ else if (fractional <= 0.75)
+ {
+ result = sign * CosForIntervalPiBy4((fractional - 0.5) * Pi, 0.0);
+ }
+ else
+ {
+ result = sign * SinForIntervalPiBy4((1.0 - fractional) * Pi, 0.0);
+ }
+ }
+ else if (ax >= 1.220703125E-4) // |x| >= 2^-13
+ {
+ result = SinForIntervalPiBy4(x * Pi, 0.0);
+ }
+ else if (ax >= 7.450580596923828E-09) // |x| >= 2^-27
+ {
+ result = x * Pi;
+ result -= result * (result * (result * (1.0 / 6.0)));
+ }
+ else
+ {
+ result = x * Pi;
+ }
+ }
+ else
+ {
+ // x is an integer
+ result = x * 0.0;
+ }
+ }
+ else
+ {
+ result = NaN;
+ }
+
+ return result;
+ }
+
///
public static double Tan(double x) => Math.Tan(x);
- // ///
- // public static double AcosPi(double x) => Math.AcosPi(x);
+ ///
+ public static double TanPi(double x)
+ {
+ // This code is based on `tanpi` 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
- // ///
- // public static double AsinPi(double x) => Math.AsinPi(x);
+ double result;
- // ///
- // public static double AtanPi(double x) => Math.AtanPi(x);
+ if (IsFinite(x))
+ {
+ double ax = Abs(x);
+ double sign = (x > 0.0) ? +1.0 : -1.0;
- // ///
- // public static double Atan2Pi(double y, double x) => Math.Atan2Pi(y, x);
+ if (ax < 4_503_599_627_370_496.0) // |x| < 2^52
+ {
+ if (ax > 0.25)
+ {
+ long integral = (long)ax;
+ double fractional = ax - integral;
- // ///
- // public static double CosPi(double x) => Math.CosPi(x);
+ if (fractional <= 0.25)
+ {
+ result = sign;
- // ///
- // public static double SinPi(double x) => Math.SinPi(x, y);
+ if (fractional != 0.00)
+ {
+ result *= TanForIntervalPiBy4(fractional * Pi, 0.0, isReciprocal: false);
+ }
+ else
+ {
+ result *= long.IsOddInteger(integral) ? -0.0 : +0.0;
+ }
+ }
+ else if (fractional <= 0.50)
+ {
+ result = sign;
+
+ if (fractional != 0.50)
+ {
+ result *= -TanForIntervalPiBy4((0.5 - fractional) * Pi, 0.0, isReciprocal: true);
+ }
+ else
+ {
+ result *= long.IsOddInteger(integral) ? NegativeInfinity : PositiveInfinity;
+ }
+ }
+ else if (fractional <= 0.75)
+ {
+ result = +sign * TanForIntervalPiBy4((fractional - 0.5) * Pi, 0.0, isReciprocal: true);
+ }
+ else
+ {
+ result = -sign * TanForIntervalPiBy4((1.0 - fractional) * Pi, 0.0, isReciprocal: false);
+ }
+ }
+ else if (ax >= 6.103515625E-05) // |x| >= 2^-14
+ {
+ result = TanForIntervalPiBy4(x * Pi, 0.0, isReciprocal: false);
+ }
+ else if (ax >= 7.450580596923828E-09) // |x| >= 2^-27
+ {
+ result = x * Pi;
+ result += (result * (result * (result * (1.0 / 3.0))));
+ }
+ else
+ {
+ result = x * Pi;
+ }
+ }
+ else if (ax < 9_007_199_254_740_992.0) // |x| < 2^53
+ {
+ // x is an integer
+ long bits = BitConverter.DoubleToInt64Bits(ax);
+ result = sign * (long.IsOddInteger(bits) ? -0.0 : +0.0);
+ }
+ else
+ {
+ // x is an even integer
+ result = sign * 0.0;
+ }
+ }
+ else
+ {
+ result = NaN;
+ }
- // ///
- // public static double TanPi(double x) => Math.TanPi(x, y);
+ return result;
+ }
//
// IUnaryNegationOperators
@@ -1726,5 +1989,197 @@ static double NegativeN(double x, int n)
///
static double IUnaryPlusOperators.operator +(double value) => (double)(+value);
+
+ //
+ // Helpers
+ //
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static double CosForIntervalPiBy4(double x, double xTail)
+ {
+ // This code is based on `cos_piby4` 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
+
+ // Taylor series for cos(x) is: 1 - (x^2 / 2!) + (x^4 / 4!) - (x^6 / 6!) ...
+ //
+ // Then define f(xx) where xx = (x * x)
+ // and f(xx) = 1 - (xx / 2!) + (xx^2 / 4!) - (xx^3 / 6!) ...
+ //
+ // We use a minimax approximation of (f(xx) - 1 + (xx / 2)) / (xx * xx)
+ // because this produces an expansion in even powers of x.
+ //
+ // If xTail is non-zero, we subtract a correction term g(x, xTail) = (x * xTail)
+ // to the result, where g(x, xTail) is an approximation to sin(x) * sin(xTail)
+ //
+ // This is valid because xTail is tiny relative to x.
+
+ const double C1 = +0.41666666666666665390037E-1; // approx: +1 / 4!
+ const double C2 = -0.13888888888887398280412E-2; // approx: -1 / 6!
+ const double C3 = +0.248015872987670414957399E-4; // approx: +1 / 8!
+ const double C4 = -0.275573172723441909470836E-6; // approx: -1 / 10!
+ const double C5 = +0.208761463822329611076335E-8; // approx: +1 / 12!
+ const double C6 = -0.113826398067944859590880E-10; // approx: -1 / 14!
+
+ double xx = x * x;
+
+ double tmp1 = 0.5 * xx;
+ double tmp2 = 1.0 - tmp1;
+
+ double result = C6;
+
+ result = (result * xx) + C5;
+ result = (result * xx) + C4;
+ result = (result * xx) + C3;
+ result = (result * xx) + C2;
+ result = (result * xx) + C1;
+
+ result *= (xx * xx);
+ result += 1.0 - tmp2 - tmp1 - (x * xTail);
+ result += tmp2;
+
+ return result;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static double SinForIntervalPiBy4(double x, double xTail)
+ {
+ // This code is based on `sin_piby4` 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
+
+ // Taylor series for sin(x) is x - (x^3 / 3!) + (x^5 / 5!) - (x^7 / 7!) ...
+ // Which can be expressed as x * (1 - (x^2 / 3!) + (x^4 /5!) - (x^6 /7!) ...)
+ //
+ // Then define f(xx) where xx = (x * x)
+ // and f(xx) = 1 - (xx / 3!) + (xx^2 / 5!) - (xx^3 / 7!) ...
+ //
+ // We use a minimax approximation of (f(xx) - 1) / xx
+ // because this produces an expansion in even powers of x.
+ //
+ // If xTail is non-zero, we add a correction term g(x, xTail) = (1 - xx / 2) * xTail
+ // to the result, where g(x, xTail) is an approximation to cos(x) * sin(xTail)
+ //
+ // This is valid because xTail is tiny relative to x.
+
+ const double C1 = -0.166666666666666646259241729; // approx: -1 / 3!
+ const double C2 = +0.833333333333095043065222816E-2; // approx: +1 / 5!
+ const double C3 = -0.19841269836761125688538679E-3; // approx: -1 / 7!
+ const double C4 = +0.275573161037288022676895908448E-5; // approx: +1 / 9!
+ const double C5 = -0.25051132068021699772257377197E-7; // approx: -1 / 11!
+ const double C6 = +0.159181443044859136852668200E-9; // approx: +1 / 13!
+
+ double xx = x * x;
+ double xxx = xx * x;
+
+ double result = C6;
+
+ result = (result * xx) + C5;
+ result = (result * xx) + C4;
+ result = (result * xx) + C3;
+ result = (result * xx) + C2;
+
+ if (xTail == 0.0)
+ {
+ result = (xx * result) + C1;
+ result = (xxx * result) + x;
+ }
+ else
+ {
+ result = x - ((xx * ((0.5 * xTail) - (xxx * result))) - xTail - (xxx * C1));
+ }
+
+ return result;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static double TanForIntervalPiBy4(double x, double xTail, bool isReciprocal)
+ {
+ // This code is based on `tan_piby4` 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
+
+ // In order to maintain relative precision transform using the identity:
+ // tan((pi / 4) - x) = (1 - tan(x)) / (1 + tan(x)) for arguments close to (pi / 4).
+ //
+ // Similarly use tan(x - (pi / 4)) = (tan(x) - 1) / (tan(x) + 1) close to (-pi / 4).
+
+ const double PiBy4Head = 7.85398163397448278999E-01;
+ const double PiBy4Tail = 3.06161699786838240164E-17;
+
+ int transform = 0;
+
+ if (x > +0.68)
+ {
+ transform = 1;
+ x = (PiBy4Head - x) + (PiBy4Tail - xTail);
+ xTail = 0.0;
+ }
+ else if (x < -0.68)
+ {
+ transform = -1;
+ x = (PiBy4Head + x) + (PiBy4Tail + xTail);
+ xTail = 0.0;
+ }
+
+ // Core Remez [2, 3] approximation to tan(x + xTail) on the interval [0, 0.68].
+
+ double tmp1 = (x * x) + (2.0 * x * xTail);
+
+ double denominator = -0.232371494088563558304549252913E-3;
+ denominator = +0.260656620398645407524064091208E-1 + (denominator * tmp1);
+ denominator = -0.515658515729031149329237816945E+0 + (denominator * tmp1);
+ denominator = +0.111713747927937668539901657944E+1 + (denominator * tmp1);
+
+ double numerator = +0.224044448537022097264602535574E-3;
+ numerator = -0.229345080057565662883358588111E-1 + (numerator * tmp1);
+ numerator = +0.372379159759792203640806338901E+0 + (numerator * tmp1);
+
+ double tmp2 = x * tmp1;
+ tmp2 *= numerator / denominator;
+ tmp2 += xTail;
+
+ // Reconstruct tan(x) in the transformed case
+
+ double result = x + tmp2;
+
+ if (transform != 0)
+ {
+ if (isReciprocal)
+ {
+ result = (transform * (2 * result / (result - 1))) - 1.0;
+ }
+ else
+ {
+ result = transform * (1.0 - (2 * result / (1 + result)));
+ }
+ }
+ else if (isReciprocal)
+ {
+ // Compute -1.0 / (x + tmp2) accurately
+
+ ulong bits = BitConverter.DoubleToUInt64Bits(result);
+ bits &= 0xFFFFFFFF00000000;
+
+ double z1 = BitConverter.UInt64BitsToDouble(bits);
+ double z2 = tmp2 - (z1 - x);
+
+ double reciprocal = -1.0 / result;
+
+ bits = BitConverter.DoubleToUInt64Bits(reciprocal);
+ bits &= 0xFFFFFFFF00000000;
+
+ double reciprocalHead = BitConverter.UInt64BitsToDouble(bits);
+ result = reciprocalHead + (reciprocal * (1.0 + (reciprocalHead * z1) + (reciprocalHead * z2)));
+ }
+
+ return result;
+ }
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Half.cs b/src/libraries/System.Private.CoreLib/src/System/Half.cs
index 2dde194b916686..f4ec37bc4c4e00 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Half.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Half.cs
@@ -1828,18 +1828,33 @@ private static bool TryConvertTo(Half value, [NotNullWhen(true)] out TOt
///
public static Half Acos(Half x) => (Half)MathF.Acos((float)x);
+ ///
+ public static Half AcosPi(Half x) => (Half)float.AcosPi((float)x);
+
///
public static Half Asin(Half x) => (Half)MathF.Asin((float)x);
+ ///
+ public static Half AsinPi(Half x) => (Half)float.AsinPi((float)x);
+
///
public static Half Atan(Half x) => (Half)MathF.Atan((float)x);
///
public static Half Atan2(Half y, Half x) => (Half)MathF.Atan2((float)y, (float)x);
+ ///
+ public static Half Atan2Pi(Half y, Half x) => (Half)float.Atan2Pi((float)y, (float)x);
+
+ ///
+ public static Half AtanPi(Half x) => (Half)float.AtanPi((float)x);
+
///
public static Half Cos(Half x) => (Half)MathF.Cos((float)x);
+ ///
+ public static Half CosPi(Half x) => (Half)float.CosPi((float)x);
+
///
public static Half Sin(Half x) => (Half)MathF.Sin((float)x);
@@ -1850,29 +1865,14 @@ public static (Half Sin, Half Cos) SinCos(Half x)
return ((Half)sin, (Half)cos);
}
+ ///
+ public static Half SinPi(Half x) => (Half)float.SinPi((float)x);
+
///
public static Half Tan(Half x) => (Half)MathF.Tan((float)x);
- // ///
- // public static Half AcosPi(Half x) => (Half)MathF.AcosPi((float)x);
-
- // ///
- // public static Half AsinPi(Half x) => (Half)MathF.AsinPi((float)x);
-
- // ///
- // public static Half AtanPi(Half x) => (Half)MathF.AtanPi((float)x);
-
- // ///
- // public static Half Atan2Pi(Half y, Half x) => (Half)MathF.Atan2Pi((float)y, (float)x);
-
- // ///
- // public static Half CosPi(Half x) => (Half)MathF.CosPi((float)x);
-
- // ///
- // public static Half SinPi(Half x) => (Half)MathF.SinPi((float)x, (float)y);
-
- // ///
- // public static Half TanPi(Half x) => (Half)MathF.TanPi((float)x, (float)y);
+ ///
+ public static Half TanPi(Half x) => (Half)float.TanPi((float)x);
//
// IUnaryNegationOperators
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/ITrigonometricFunctions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/ITrigonometricFunctions.cs
index 9a073e4eb80e1d..4ba25bebbfd9d4 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/ITrigonometricFunctions.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/ITrigonometricFunctions.cs
@@ -9,53 +9,95 @@ public interface ITrigonometricFunctions
where TSelf : ITrigonometricFunctions, INumberBase
{
/// Computes the arc-cosine of a value.
- /// The value, in radians, whose arc-cosine is to be computed.
+ /// The value whose arc-cosine is to be computed.
/// The arc-cosine of .
+ /// This computes arccos(x) in the interval [+0, +π] radians.
static abstract TSelf Acos(TSelf x);
+ /// Computes the arc-cosine of a value and divides the result by pi.
+ /// The value whose arc-cosine is to be computed.
+ /// The arc-cosine of , divided by pi.
+ /// This computes arccos(x) / π in the interval [-0.5, +0.5].
+ static abstract TSelf AcosPi(TSelf x);
+
/// Computes the arc-sine of a value.
- /// The value, in radians, whose arc-sine is to be computed.
+ /// The value whose arc-sine is to be computed.
/// The arc-sine of .
+ /// This computes arcsin(x) in the interval [-π / 2, +π / 2] radians.
static abstract TSelf Asin(TSelf x);
+ /// Computes the arc-sine of a value and divides the result by pi.
+ /// The value whose arc-sine is to be computed.
+ /// The arc-sine of , divided by pi.
+ /// This computes arcsin(x) / π in the interval [-0.5, +0.5].
+ static abstract TSelf AsinPi(TSelf x);
+
/// Computes the arc-tangent of a value.
- /// The value, in radians, whose arc-tangent is to be computed.
+ /// The value whose arc-tangent is to be computed.
/// The arc-tangent of .
+ /// This computes arctan(x) in the interval [-π / 2, +π / 2] radians.
static abstract TSelf Atan(TSelf x);
- /// Computes the arc-tangent of the quotient of two values.
+ /// Computes the arc-tangent for the quotient of two values.
/// The y-coordinate of a point.
/// The x-coordinate of a point.
/// The arc-tangent of divided-by .
+ /// This computes arctan(y / x) in the interval [-π, +π] radians.
static abstract TSelf Atan2(TSelf y, TSelf x);
+ /// Computes the arc-tangent for the quotient of two values and divides the result by pi.
+ /// The y-coordinate of a point.
+ /// The x-coordinate of a point.
+ /// The arc-tangent of divided-by , divided by pi.
+ /// This computes arctan(y / x) / π in the interval [-1, +1].
+ static abstract TSelf Atan2Pi(TSelf y, TSelf x);
+
+ /// Computes the arc-tangent of a value and divides the result by pi.
+ /// The value whose arc-tangent is to be computed.
+ /// The arc-tangent of , divided by pi.
+ /// This computes arctan(x) / π in the interval [-0.5, +0.5].
+ static abstract TSelf AtanPi(TSelf x);
+
/// Computes the cosine of a value.
/// The value, in radians, whose cosine is to be computed.
/// The cosine of .
+ /// This computes cos(x).
static abstract TSelf Cos(TSelf x);
+ /// Computes the cosine of a value that has been multipled by pi.
+ /// The value, in half-revolutions, whose cosine is to be computed.
+ /// The cosine of multiplied-by pi.
+ /// This computes cos(x * π).
+ static abstract TSelf CosPi(TSelf x);
+
/// Computes the sine of a value.
/// The value, in radians, whose sine is to be computed.
/// The sine of .
+ /// This computes sin(x).
static abstract TSelf Sin(TSelf x);
/// Computes the sine and cosine of a value.
/// The value, in radians, whose sine and cosine are to be computed.
/// The sine and cosine of .
+ /// This computes (sin(x), cos(x)).
static abstract (TSelf Sin, TSelf Cos) SinCos(TSelf x);
+ /// Computes the sine of a value that has been multipled by pi.
+ /// The value, in half-revolutions, that is multipled by pi before computing its sine.
+ /// The sine of multiplied-by pi.
+ /// This computes sin(x * π).
+ static abstract TSelf SinPi(TSelf x);
+
/// Computes the tangent of a value.
/// The value, in radians, whose tangent is to be computed.
/// The tangent of .
+ /// This computes tan(x).
static abstract TSelf Tan(TSelf x);
- // The following methods are approved but not yet implemented in the libraries
- // * static abstract TSelf AcosPi(TSelf x);
- // * static abstract TSelf AsinPi(TSelf x);
- // * static abstract TSelf AtanPi(TSelf x);
- // * static abstract TSelf Atan2Pi(TSelf y, TSelf x);
- // * static abstract TSelf CosPi(TSelf x);
- // * static abstract TSelf SinPi(TSelf x);
- // * static abstract TSelf TanPi(TSelf x);
+ /// Computes the tangent of a value that has been multipled by pi.
+ /// The value, in half-revolutions, that is multipled by pi before computing its tangent.
+ /// The tangent of multiplied-by pi.
+ /// This computes tan(x * π).
+ static abstract TSelf TanPi(TSelf x);
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs
index b3f4213a29b1ae..942fe97fe644bd 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/NFloat.cs
@@ -1733,18 +1733,33 @@ private static bool TryConvertTo(NFloat value, [NotNullWhen(true)] out T
///
public static NFloat Acos(NFloat x) => new NFloat(NativeType.Acos(x._value));
+ ///
+ public static NFloat AcosPi(NFloat x) => new NFloat(NativeType.AcosPi(x._value));
+
///
public static NFloat Asin(NFloat x) => new NFloat(NativeType.Asin(x._value));
+ ///
+ public static NFloat AsinPi(NFloat x) => new NFloat(NativeType.AsinPi(x._value));
+
///
public static NFloat Atan(NFloat x) => new NFloat(NativeType.Atan(x._value));
///
public static NFloat Atan2(NFloat y, NFloat x) => new NFloat(NativeType.Atan2(y._value, x._value));
+ ///
+ public static NFloat Atan2Pi(NFloat y, NFloat x) => new NFloat(NativeType.Atan2Pi(y._value, x._value));
+
+ ///
+ public static NFloat AtanPi(NFloat x) => new NFloat(NativeType.AtanPi(x._value));
+
///
public static NFloat Cos(NFloat x) => new NFloat(NativeType.Cos(x._value));
+ ///
+ public static NFloat CosPi(NFloat x) => new NFloat(NativeType.CosPi(x._value));
+
///
public static NFloat Sin(NFloat x) => new NFloat(NativeType.Sin(x._value));
@@ -1755,28 +1770,13 @@ public static (NFloat Sin, NFloat Cos) SinCos(NFloat x)
return (new NFloat(sin), new NFloat(cos));
}
+ ///
+ public static NFloat SinPi(NFloat x) => new NFloat(NativeType.SinPi(x._value));
+
///
public static NFloat Tan(NFloat x) => new NFloat(NativeType.Tan(x._value));
- // ///
- // public static NFloat AcosPi(NFloat x) => new NFloat(NativeType.AcosPi(x._value));
-
- // ///
- // public static NFloat AsinPi(NFloat x) => new NFloat(NativeType.AsinPi(x._value));
-
- // ///
- // public static NFloat AtanPi(NFloat x) => new NFloat(NativeType.AtanPi(x._value));
-
- // ///
- // public static NFloat Atan2Pi(NFloat y, NFloat x) => new NFloat(NativeType.Atan2Pi(y._value, x._value));
-
- // ///
- // public static NFloat CosPi(NFloat x) => new NFloat(NativeType.CosPi(x._value));
-
- // ///
- // public static NFloat SinPi(NFloat x) => new NFloat(NativeType.SinPi(x._value, y._value));
-
- // ///
- // public static NFloat TanPi(NFloat x) => new NFloat(NativeType.TanPi(x._value, y._value));
+ ///
+ public static NFloat TanPi(NFloat x) => new NFloat(NativeType.TanPi(x._value));
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Single.cs b/src/libraries/System.Private.CoreLib/src/System/Single.cs
index 2d45346b5c9ede..b71cc590f2f1d8 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Single.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Single.cs
@@ -1548,47 +1548,310 @@ static float NegativeN(float x, int n)
///
public static float Acos(float x) => MathF.Acos(x);
+ ///
+ public static float AcosPi(float x)
+ {
+ return Acos(x) / Pi;
+ }
+
///
public static float Asin(float x) => MathF.Asin(x);
+ ///
+ public static float AsinPi(float x)
+ {
+ return Asin(x) / Pi;
+ }
+
///
public static float Atan(float x) => MathF.Atan(x);
///
public static float Atan2(float y, float x) => MathF.Atan2(y, x);
+ ///
+ public static float Atan2Pi(float y, float x)
+ {
+ return Atan2(y, x) / Pi;
+ }
+
+ ///
+ public static float AtanPi(float x)
+ {
+ return Atan(x) / Pi;
+ }
+
///
public static float Cos(float x) => MathF.Cos(x);
+ ///
+ public static float CosPi(float x)
+ {
+ // This code is based on `cospif` 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))
+ {
+ float ax = Abs(x);
+
+ if (ax < 8_388_608.0f) // |x| < 2^23
+ {
+ if (ax > 0.25f)
+ {
+ int integral = (int)ax;
+
+ float fractional = ax - integral;
+ float sign = int.IsOddInteger(integral) ? -1.0f : +1.0f;
+
+ if (fractional <= 0.25f)
+ {
+ result = sign;
+
+ if (fractional != 0.00f)
+ {
+ result *= CosForIntervalPiBy4(fractional * Pi);
+ }
+ }
+ else if (fractional <= 0.50f)
+ {
+ if (fractional != 0.50f)
+ {
+ result = sign * SinForIntervalPiBy4((0.5f - fractional) * Pi);
+ }
+ else
+ {
+ result = 0.0f;
+ }
+ }
+ else if (fractional <= 0.75)
+ {
+ result = -sign * SinForIntervalPiBy4((fractional - 0.5f) * Pi);
+ }
+ else
+ {
+ result = -sign * CosForIntervalPiBy4((1.0f - fractional) * Pi);
+ }
+ }
+ else if (ax >= 7.8125E-3f) // |x| >= 2^-7
+ {
+ result = CosForIntervalPiBy4(x * Pi);
+ }
+ else if (ax >= 1.22070313E-4f) // |x| >= 2^-13
+ {
+ result = x * Pi;
+ result = 1.0f - (result * result * 0.5f);
+ }
+ else
+ {
+ result = 1.0f;
+ }
+ }
+ else if (ax < 16_777_216.0f) // |x| < 2^24
+ {
+ // x is an integer
+ int bits = BitConverter.SingleToInt32Bits(ax);
+ result = int.IsOddInteger(bits) ? -1.0f : +1.0f;
+ }
+ else
+ {
+ // x is an even integer
+ result = 1.0f;
+ }
+ }
+ else
+ {
+ result = NaN;
+ }
+
+ return result;
+ }
+
///
public static float Sin(float x) => MathF.Sin(x);
///
public static (float Sin, float Cos) SinCos(float x) => MathF.SinCos(x);
+ ///
+ public static float SinPi(float x)
+ {
+ // This code is based on `sinpif` 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))
+ {
+ float ax = Abs(x);
+
+ if (ax < 8_388_608.0f) // |x| < 2^23
+ {
+ if (ax > 0.25f)
+ {
+ int integral = (int)ax;
+
+ float fractional = ax - integral;
+ float sign = ((x > 0.0f) ? +1.0f : -1.0f) * (int.IsOddInteger(integral) ? -1.0f : +1.0f);
+
+ if (fractional <= 0.25f)
+ {
+ if (fractional != 0.00f)
+ {
+ result = sign * SinForIntervalPiBy4(fractional * Pi);
+ }
+ else
+ {
+ result = x * 0.0f;
+ }
+ }
+ else if (fractional <= 0.50f)
+ {
+ result = sign;
+
+ if (fractional != 0.50f)
+ {
+ result *= CosForIntervalPiBy4((0.5f - fractional) * Pi);
+ }
+ }
+ else if (fractional <= 0.75f)
+ {
+ result = sign * CosForIntervalPiBy4((fractional - 0.5f) * Pi);
+ }
+ else
+ {
+ result = sign * SinForIntervalPiBy4((1.0f - fractional) * Pi);
+ }
+ }
+ else if (ax >= 7.8125E-3f) // |x| >= 2^-7
+ {
+ result = SinForIntervalPiBy4(x * Pi);
+ }
+ else if (ax >= 1.22070313E-4f) // |x| >= 2^-13
+ {
+ result = x * Pi;
+ result -= result * (result * (result * (1.0f / 6.0f)));
+ }
+ else
+ {
+ result = x * Pi;
+ }
+ }
+ else
+ {
+ // x is an integer
+ result = x * 0.0f;
+ }
+ }
+ else
+ {
+ result = NaN;
+ }
+
+ return result;
+ }
+
///
public static float Tan(float x) => MathF.Tan(x);
- // ///
- // public static float AcosPi(float x) => MathF.AcosPi(x);
-
- // ///
- // public static float AsinPi(float x) => MathF.AsinPi(x);
+ ///
+ public static float TanPi(float x)
+ {
+ // This code is based on `tanpif` 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
- // ///
- // public static float AtanPi(float x) => MathF.AtanPi(x);
+ float result;
- // ///
- // public static float Atan2Pi(float y, float x) => MathF.Atan2Pi(y, x);
+ if (IsFinite(x))
+ {
+ float ax = Abs(x);
+ float sign = (x > 0.0f) ? +1.0f : -1.0f;
- // ///
- // public static float CosPi(float x) => MathF.CosPi(x);
+ if (ax < 8_388_608.0f) // |x| < 2^23
+ {
+ if (ax > 0.25f)
+ {
+ int integral = (int)ax;
+ float fractional = ax - integral;
- // ///
- // public static float SinPi(float x) => MathF.SinPi(x, y);
+ if (fractional <= 0.25f)
+ {
+ result = sign;
+
+ if (fractional != 0.00f)
+ {
+ result *= TanForIntervalPiBy4(fractional * Pi, isReciprocal: false);
+ }
+ else
+ {
+ result *= int.IsOddInteger(integral) ? -0.0f : +0.0f;
+ }
+ }
+ else if (fractional <= 0.50f)
+ {
+ result = sign;
+
+ if (fractional != 0.50f)
+ {
+ result *= -TanForIntervalPiBy4((0.5f - fractional) * Pi, isReciprocal: true);
+ }
+ else
+ {
+ result *= int.IsOddInteger(integral) ? NegativeInfinity : PositiveInfinity;
+ }
+ }
+ else if (fractional <= 0.75f)
+ {
+ result = +sign * TanForIntervalPiBy4((fractional - 0.5f) * Pi, isReciprocal: true);
+ }
+ else
+ {
+ result = -sign * TanForIntervalPiBy4((1.0f - fractional) * Pi, isReciprocal: false);
+ }
+ }
+ else if (ax >= 7.8125E-3f) // |x| >= 2^-7
+ {
+ result = TanForIntervalPiBy4(x * Pi, isReciprocal: false);
+ }
+ else if (ax >= 1.22070313E-4f) // |x| >= 2^-13
+ {
+ result = x * Pi;
+ result += (result * (result * (result * (1.0f / 3.0f))));
+ }
+ else
+ {
+ result = x * Pi;
+ }
+ }
+ else if (ax < 16_777_216) // |x| < 2^24
+ {
+ // x is an integer
+ int bits = BitConverter.SingleToInt32Bits(ax);
+ result = sign * (int.IsOddInteger(bits) ? -0.0f : +0.0f);
+ }
+ else
+ {
+ // x is an even integer
+ result = sign * 0.0f;
+ }
+ }
+ else
+ {
+ result = NaN;
+ }
- // ///
- // public static float TanPi(float x) => MathF.TanPi(x, y);
+ return result;
+ }
//
// IUnaryNegationOperators
@@ -1603,5 +1866,112 @@ static float NegativeN(float x, int n)
///
static float IUnaryPlusOperators.operator +(float value) => (float)(+value);
+
+ //
+ // Helpers
+ //
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static float CosForIntervalPiBy4(float x)
+ {
+ // This code is based on `cos_piby4` 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
+
+ // Taylor series for cos(x) is: 1 - (x^2 / 2!) + (x^4 / 4!) - (x^6 / 6!) ...
+ //
+ // Then define f(xx) where xx = (x * x)
+ // and f(xx) = 1 - (xx / 2!) + (xx^2 / 4!) - (xx^3 / 6!) ...
+ //
+ // We use a minimax approximation of (f(xx) - 1 + (xx / 2)) / (xx * xx)
+ // because this produces an expansion in even powers of x.
+
+ const double C1 = +0.41666666666666665390037E-1; // approx: +1 / 4!
+ const double C2 = -0.13888888888887398280412E-2; // approx: -1 / 6!
+ const double C3 = +0.248015872987670414957399E-4; // approx: +1 / 8!
+ const double C4 = -0.275573172723441909470836E-6; // approx: -1 / 10!
+
+ double xx = x * x;
+ double result = C4;
+
+ result = (result * xx) + C3;
+ result = (result * xx) + C2;
+ result = (result * xx) + C1;
+
+ result *= xx * xx;
+ result += 1.0 - (0.5 * xx);
+
+ return (float)result;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static float SinForIntervalPiBy4(float x)
+ {
+ // This code is based on `sin_piby4` 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
+
+ // Taylor series for sin(x) is x - (x^3 / 3!) + (x^5 / 5!) - (x^7 / 7!) ...
+ // Which can be expressed as x * (1 - (x^2 / 3!) + (x^4 /5!) - (x^6 /7!) ...)
+ //
+ // Then define f(xx) where xx = (x * x)
+ // and f(xx) = 1 - (xx / 3!) + (xx^2 / 5!) - (xx^3 / 7!) ...
+ //
+ // We use a minimax approximation of (f(xx) - 1) / xx
+ // because this produces an expansion in even powers of x.
+
+ const double C1 = -0.166666666666666646259241729; // approx: -1 / 3!
+ const double C2 = +0.833333333333095043065222816E-2; // approx: +1 / 5!
+ const double C3 = -0.19841269836761125688538679E-3; // approx: -1 / 7!
+ const double C4 = +0.275573161037288022676895908448E-5; // approx: +1 / 9!
+
+ double xx = x * x;
+ double result = C4;
+
+ result = (result * xx) + C3;
+ result = (result * xx) + C2;
+ result = (result * xx) + C1;
+
+ result *= x * xx;
+ result += x;
+
+ return (float)result;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static float TanForIntervalPiBy4(float x, bool isReciprocal)
+ {
+ // This code is based on `tan_piby4` 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
+
+ // Core Remez [1, 2] approximation to tan(x) on the interval [0, pi / 4].
+
+ double xx = x * x;
+
+ double denominator = +0.1844239256901656082986661E-1;
+ denominator = -0.51396505478854532132342E+0 + (denominator * xx);
+ denominator = +0.115588821434688393452299E+1 + (denominator * xx);
+
+ double numerator = -0.172032480471481694693109E-1;
+ numerator = 0.385296071263995406715129E+0 + (numerator * xx);
+
+ double result = x * xx;
+ result *= numerator / denominator;
+ result += x;
+
+ if (isReciprocal)
+ {
+ result = -1.0 / result;
+ }
+
+ return (float)result;
+ }
}
}
diff --git a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs
index 75eca17032a4a1..ba4ccb2687d385 100644
--- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs
+++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs
@@ -838,11 +838,15 @@ public static void Free(void* ptr) { }
public static System.Runtime.InteropServices.NFloat Abs(System.Runtime.InteropServices.NFloat value) { throw null; }
public static System.Runtime.InteropServices.NFloat Acos(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat Acosh(System.Runtime.InteropServices.NFloat x) { throw null; }
+ public static System.Runtime.InteropServices.NFloat AcosPi(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat Asin(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat Asinh(System.Runtime.InteropServices.NFloat x) { throw null; }
+ public static System.Runtime.InteropServices.NFloat AsinPi(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat Atan(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat Atan2(System.Runtime.InteropServices.NFloat y, System.Runtime.InteropServices.NFloat x) { throw null; }
+ public static System.Runtime.InteropServices.NFloat Atan2Pi(System.Runtime.InteropServices.NFloat y, System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat Atanh(System.Runtime.InteropServices.NFloat x) { throw null; }
+ public static System.Runtime.InteropServices.NFloat AtanPi(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat BitDecrement(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat BitIncrement(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat Cbrt(System.Runtime.InteropServices.NFloat x) { throw null; }
@@ -853,6 +857,7 @@ public static void Free(void* ptr) { }
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 static System.Runtime.InteropServices.NFloat CosPi(System.Runtime.InteropServices.NFloat x) { throw null; }
public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; }
public bool Equals(System.Runtime.InteropServices.NFloat other) { throw null; }
public static System.Runtime.InteropServices.NFloat Exp(System.Runtime.InteropServices.NFloat x) { throw null; }
@@ -995,6 +1000,7 @@ public static void Free(void* ptr) { }
public static System.Runtime.InteropServices.NFloat Sin(System.Runtime.InteropServices.NFloat x) { throw null; }
public static (System.Runtime.InteropServices.NFloat Sin, System.Runtime.InteropServices.NFloat Cos) SinCos(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat Sinh(System.Runtime.InteropServices.NFloat x) { throw null; }
+ public static System.Runtime.InteropServices.NFloat SinPi(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat Sqrt(System.Runtime.InteropServices.NFloat x) { throw null; }
static System.Runtime.InteropServices.NFloat System.Numerics.IAdditionOperators.operator checked +(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right) { throw null; }
static System.Runtime.InteropServices.NFloat System.Numerics.IBitwiseOperators.operator &(System.Runtime.InteropServices.NFloat left, System.Runtime.InteropServices.NFloat right) { throw null; }
@@ -1027,6 +1033,7 @@ public static void Free(void* ptr) { }
static System.Runtime.InteropServices.NFloat System.Numerics.IUnaryNegationOperators.operator checked -(System.Runtime.InteropServices.NFloat value) { throw null; }
public static System.Runtime.InteropServices.NFloat Tan(System.Runtime.InteropServices.NFloat x) { throw null; }
public static System.Runtime.InteropServices.NFloat Tanh(System.Runtime.InteropServices.NFloat x) { throw null; }
+ public static System.Runtime.InteropServices.NFloat TanPi(System.Runtime.InteropServices.NFloat x) { throw null; }
public override string ToString() { throw null; }
public string ToString(System.IFormatProvider? provider) { throw null; }
public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; }
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/NFloatTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/NFloatTests.cs
index fb12b52eebb926..ec31ffcaaff513 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/NFloatTests.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/NFloatTests.cs
@@ -1474,7 +1474,7 @@ public static void Log10P1Test32(float value, float expectedResult, float allowe
[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.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))
@@ -1545,7 +1545,7 @@ public static void Hypot32(float x, float y, float expectedResult, float allowed
[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(-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)]
@@ -1606,6 +1606,165 @@ public static void Root32(float x, int n, float expectedResult, float allowedVar
AssertExtensions.Equal(expectedResult, NFloat.Root(x, n), allowedVariance);
}
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))]
+ [InlineData( float.NaN, float.NaN, 0.0f)]
+ [InlineData( 1.0f, 0.0f, 0.0f)]
+ [InlineData( 0.540302306f, 0.318309886f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 0.204957194f, 0.434294482f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 0.0f, 0.5f, CrossPlatformMachineEpsilon32)] // This should be exact, but has an issue on WASM/Unix
+ [InlineData(-0.416146837f, 0.636619772f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-0.570233249f, 0.693147181f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-0.605699867f, 0.707106781f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-0.781211892f, 0.785398163f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-1.0f, 1.0f, CrossPlatformMachineEpsilon32)] // This should be exact, but has an issue on WASM/Unix
+ [InlineData(-0.919764995f, 0.871620833f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-0.266255342f, 0.585786438f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-0.179057946f, 0.557304959f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 0.220584041f, 0.429203673f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 0.581195664f, 0.302585093f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-0.633255651f, 0.718281828f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-0.902685362f, 0.858407346f, CrossPlatformMachineEpsilon32)]
+ public static void AcosPiTest32(float value, float expectedResult, float allowedVariance)
+ {
+ AssertExtensions.Equal(expectedResult, (float)NFloat.AcosPi(value), allowedVariance);
+ }
+
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))]
+ [InlineData( float.NaN, float.NaN, 0.0f)]
+ [InlineData( 0.0f, 0.0f, 0.0f)]
+ [InlineData( 0.841470985f, 0.318309886f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 0.978770938f, 0.434294482f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 1.0f, 0.5f, CrossPlatformMachineEpsilon32)] // This should be exact, but has an issue on WASM/Unix
+ [InlineData( 0.909297427f, 0.363380228f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 0.821482831f, 0.306852819f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 0.795693202f, 0.292893219f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 0.624265953f, 0.214601837f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-0.392469559f, -0.128379167f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-0.963902533f, -0.414213562f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-0.983838529f, -0.442695041f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-0.975367972f, -0.429203673f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 0.813763848f, 0.302585093f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 0.773942685f, 0.281718172f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-0.430301217f, -0.141592654f, CrossPlatformMachineEpsilon32)]
+ public static void AsinPiTest32(float value, float expectedResult, float allowedVariance)
+ {
+ AssertExtensions.Equal(-expectedResult, (float)NFloat.AsinPi(-value), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, (float)NFloat.AsinPi(+value), allowedVariance);
+ }
+
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))]
+ [InlineData( float.NaN, float.NaN, 0.0f)]
+ [InlineData( 0.0f, 0.0f, 0.0f)]
+ [InlineData( 1.55740773f, 0.318309886f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 4.77548954f, 0.434294482f, CrossPlatformMachineEpsilon32)]
+ [InlineData( float.PositiveInfinity, 0.5f, CrossPlatformMachineEpsilon32)] // This should be exact, but has an issue on WASM/Unix
+ [InlineData(-2.18503986f, -0.363380228f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-1.44060844f, -0.306852819f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-1.31367571f, -0.292893219f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-0.79909940f, -0.214601837f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 0.42670634f, 0.128379167f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 3.62021857f, 0.414213562f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 5.49452594f, 0.442695041f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-4.42175222f, -0.429203673f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 1.40015471f, 0.302585093f, CrossPlatformMachineEpsilon32)]
+ [InlineData(-1.22216467f, -0.281718172f, CrossPlatformMachineEpsilon32)]
+ [InlineData( 0.476690146f, 0.141592654f, CrossPlatformMachineEpsilon32)]
+ public static void AtanPiTest32(float value, float expectedResult, float allowedVariance)
+ {
+ AssertExtensions.Equal(-expectedResult, (float)NFloat.AtanPi(-value), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, (float)NFloat.AtanPi(+value), allowedVariance);
+ }
+
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))]
+ [InlineData(float.NaN, float.NaN, 0.0f)]
+ [InlineData(0.0f, 1.0f, 0.0f)]
+ [InlineData(0.318309886f, 0.540302306f, CrossPlatformMachineEpsilon32)] // value: (1 / pi)
+ [InlineData(0.434294482f, 0.204957194f, CrossPlatformMachineEpsilon32)] // value: (log10(e))
+ [InlineData(0.5f, 0.0f, 0.0f)]
+ [InlineData(0.636619772f, -0.416146837f, CrossPlatformMachineEpsilon32)] // value: (2 / pi)
+ [InlineData(0.693147181f, -0.570233249f, CrossPlatformMachineEpsilon32)] // value: (ln(2))
+ [InlineData(0.707106781f, -0.605699867f, CrossPlatformMachineEpsilon32)] // value: (1 / sqrt(2))
+ [InlineData(0.785398163f, -0.781211892f, CrossPlatformMachineEpsilon32)] // value: (pi / 4)
+ [InlineData(1.0f, -1.0f, 0.0f)]
+ [InlineData(1.12837917f, -0.919764995f, CrossPlatformMachineEpsilon32)] // value: (2 / sqrt(pi))
+ [InlineData(1.41421356f, -0.266255342f, CrossPlatformMachineEpsilon32)] // value: (sqrt(2))
+ [InlineData(1.44269504f, -0.179057946f, CrossPlatformMachineEpsilon32)] // value: (log2(e))
+ [InlineData(1.5f, 0.0f, 0.0f)]
+ [InlineData(1.57079633f, 0.220584041f, CrossPlatformMachineEpsilon32)] // value: (pi / 2)
+ [InlineData(2.0f, 1.0f, 0.0f)]
+ [InlineData(2.30258509f, 0.581195664f, CrossPlatformMachineEpsilon32)] // value: (ln(10))
+ [InlineData(2.5f, 0.0f, 0.0f)]
+ [InlineData(2.71828183f, -0.633255651f, CrossPlatformMachineEpsilon32)] // value: (e)
+ [InlineData(3.0f, -1.0f, 0.0f)]
+ [InlineData(3.14159265f, -0.902685362f, CrossPlatformMachineEpsilon32)] // value: (pi)
+ [InlineData(3.5f, 0.0f, 0.0f)]
+ [InlineData(float.PositiveInfinity, float.NaN, 0.0f)]
+ public static void CosPiTest32(float value, float expectedResult, float allowedVariance)
+ {
+ AssertExtensions.Equal(+expectedResult, (float)NFloat.CosPi(-value), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, (float)NFloat.CosPi(+value), allowedVariance);
+ }
+
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))]
+ [InlineData(float.NaN, float.NaN, 0.0f)]
+ [InlineData(0.0f, 0.0f, 0.0f)]
+ [InlineData(0.318309886f, 0.841470985f, CrossPlatformMachineEpsilon32)] // value: (1 / pi)
+ [InlineData(0.434294482f, 0.978770938f, CrossPlatformMachineEpsilon32)] // value: (log10(e))
+ [InlineData(0.5f, 1.0f, 0.0f)]
+ [InlineData(0.636619772f, 0.909297427f, CrossPlatformMachineEpsilon32)] // value: (2 / pi)
+ [InlineData(0.693147181f, 0.821482831f, CrossPlatformMachineEpsilon32)] // value: (ln(2))
+ [InlineData(0.707106781f, 0.795693202f, CrossPlatformMachineEpsilon32)] // value: (1 / sqrt(2))
+ [InlineData(0.785398163f, 0.624265953f, CrossPlatformMachineEpsilon32)] // value: (pi / 4)
+ [InlineData(1.0f, 0.0f, 0.0f)]
+ [InlineData(1.12837917f, -0.392469559f, CrossPlatformMachineEpsilon32)] // value: (2 / sqrt(pi))
+ [InlineData(1.41421356f, -0.963902533f, CrossPlatformMachineEpsilon32)] // value: (sqrt(2))
+ [InlineData(1.44269504f, -0.983838529f, CrossPlatformMachineEpsilon32)] // value: (log2(e))
+ [InlineData(1.5f, -1.0f, 0.0f)]
+ [InlineData(1.57079633f, -0.975367972f, CrossPlatformMachineEpsilon32)] // value: (pi / 2)
+ [InlineData(2.0f, 0.0f, 0.0f)]
+ [InlineData(2.30258509f, 0.813763848f, CrossPlatformMachineEpsilon32)] // value: (ln(10))
+ [InlineData(2.5f, 1.0f, 0.0f)]
+ [InlineData(2.71828183f, 0.773942685f, CrossPlatformMachineEpsilon32)] // value: (e)
+ [InlineData(3.0f, 0.0f, 0.0f)]
+ [InlineData(3.14159265f, -0.430301217f, CrossPlatformMachineEpsilon32)] // value: (pi)
+ [InlineData(3.5f, -1.0f, 0.0f)]
+ [InlineData(float.PositiveInfinity, float.NaN, 0.0f)]
+ public static void SinPiTest32(float value, float expectedResult, float allowedVariance)
+ {
+ AssertExtensions.Equal(-expectedResult, (float)NFloat.SinPi(-value), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, (float)NFloat.SinPi(+value), allowedVariance);
+ }
+
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))]
+ [InlineData(float.NaN, float.NaN, 0.0f)]
+ [InlineData(0.0f, 0.0f, 0.0f)]
+ [InlineData(0.318309886f, 1.55740772f, CrossPlatformMachineEpsilon32 * 10)] // value: (1 / pi)
+ [InlineData(0.434294482f, 4.77548954f, CrossPlatformMachineEpsilon32 * 10)] // value: (log10(e))
+ [InlineData(0.5f, float.PositiveInfinity, 0.0f)]
+ [InlineData(0.636619772f, -2.18503986f, CrossPlatformMachineEpsilon32 * 10)] // value: (2 / pi)
+ [InlineData(0.693147181f, -1.44060844f, CrossPlatformMachineEpsilon32 * 10)] // value: (ln(2))
+ [InlineData(0.707106781f, -1.31367571f, CrossPlatformMachineEpsilon32 * 10)] // value: (1 / sqrt(2))
+ [InlineData(0.785398163f, -0.799099398f, CrossPlatformMachineEpsilon32)] // value: (pi / 4)
+ [InlineData(1.0f, -0.0f, 0.0f)]
+ [InlineData(1.12837917f, 0.426706344f, CrossPlatformMachineEpsilon32)] // value: (2 / sqrt(pi))
+ [InlineData(1.41421356f, 3.62021857f, CrossPlatformMachineEpsilon32 * 10)] // value: (sqrt(2))
+ [InlineData(1.44269504f, 5.49452594f, CrossPlatformMachineEpsilon32 * 10)] // value: (log2(e))
+ [InlineData(1.5f, float.NegativeInfinity, 0.0f)]
+ [InlineData(1.57079633f, -4.42175222f, CrossPlatformMachineEpsilon32 * 10)] // value: (pi / 2)
+ [InlineData(2.0f, 0.0f, 0.0f)]
+ [InlineData(2.30258509f, 1.40015471f, CrossPlatformMachineEpsilon32 * 10)] // value: (ln(10))
+ [InlineData(2.5f, float.PositiveInfinity, 0.0f)]
+ [InlineData(2.71828183f, -1.22216467f, CrossPlatformMachineEpsilon32 * 10)] // value: (e)
+ [InlineData(3.0f, -0.0f, 0.0f)]
+ [InlineData(3.14159265f, 0.476690146f, CrossPlatformMachineEpsilon32)] // value: (pi)
+ [InlineData(3.5f, float.NegativeInfinity, 0.0f)]
+ [InlineData(float.PositiveInfinity, float.NaN, 0.0f)]
+ public static void TanPiTest32(float value, float expectedResult, float allowedVariance)
+ {
+ AssertExtensions.Equal(-expectedResult, (float)NFloat.TanPi(-value), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, (float)NFloat.TanPi(+value), allowedVariance);
+ }
+
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))]
[InlineData( double.NegativeInfinity, -1.0, 0.0)]
[InlineData(-3.1415926535897932, -0.95678608173622775, CrossPlatformMachineEpsilon64)] // value: -(pi)
@@ -1958,7 +2117,7 @@ public static void Log10P1Test64(double value, double expectedResult, double all
[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.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))
@@ -2029,7 +2188,7 @@ public static void Hypot64(double x, double y, double expectedResult, double all
[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(-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)]
@@ -2089,5 +2248,164 @@ public static void Root64(double x, int n, double expectedResult, double allowed
{
AssertExtensions.Equal(expectedResult, NFloat.Root((NFloat)x, n), allowedVariance);
}
+
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))]
+ [InlineData( double.NaN, double.NaN, 0.0)]
+ [InlineData( 1.0, 0.0, 0.0)]
+ [InlineData( 0.54030230586813972, 0.31830988618379067, CrossPlatformMachineEpsilon64)]
+ [InlineData( 0.20495719432643395, 0.43429448190325183, CrossPlatformMachineEpsilon64)]
+ [InlineData( 0.0, 0.5, 0.0)]
+ [InlineData(-0.41614683654714239, 0.63661977236758134, CrossPlatformMachineEpsilon64)]
+ [InlineData(-0.57023324876887755, 0.69314718055994531, CrossPlatformMachineEpsilon64)]
+ [InlineData(-0.60569986707881343, 0.70710678118654752, CrossPlatformMachineEpsilon64)]
+ [InlineData(-0.78121189211048819, 0.78539816339744831, CrossPlatformMachineEpsilon64)]
+ [InlineData(-1.0, 1.0, 0.0)]
+ [InlineData(-0.91976499476851874, 0.87162083290448743, CrossPlatformMachineEpsilon64)]
+ [InlineData(-0.26625534204141549, 0.58578643762690495, CrossPlatformMachineEpsilon64)]
+ [InlineData(-0.17905794598427576, 0.55730495911103659, CrossPlatformMachineEpsilon64)]
+ [InlineData( 0.22058404074969809, 0.42920367320510338, CrossPlatformMachineEpsilon64)]
+ [InlineData( 0.58119566361426737, 0.30258509299404568, CrossPlatformMachineEpsilon64)]
+ [InlineData(-0.63325565131482003, 0.71828182845904523, CrossPlatformMachineEpsilon64)]
+ [InlineData(-0.90268536193307107, 0.85840734641020676, CrossPlatformMachineEpsilon64)]
+ public static void AcosPiTest64(double value, double expectedResult, double allowedVariance)
+ {
+ AssertExtensions.Equal(expectedResult, NFloat.AcosPi((NFloat)(value)), allowedVariance);
+ }
+
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))]
+ [InlineData( double.NaN, double.NaN, 0.0)]
+ [InlineData( 0.0, 0.0, 0.0)]
+ [InlineData( 0.84147098480789651, 0.31830988618379067, CrossPlatformMachineEpsilon64)]
+ [InlineData( 0.97877093770393305, 0.43429448190325183, CrossPlatformMachineEpsilon64)]
+ [InlineData( 1.0, 0.5, 0.0)]
+ [InlineData( 0.90929742682568170, 0.36338022763241866, CrossPlatformMachineEpsilon64)]
+ [InlineData( 0.82148283122563883, 0.30685281944005469, CrossPlatformMachineEpsilon64)]
+ [InlineData( 0.79569320156748087, 0.29289321881345248, CrossPlatformMachineEpsilon64)]
+ [InlineData( 0.62426595263969903, 0.21460183660255169, CrossPlatformMachineEpsilon64)]
+ [InlineData(-0.39246955856278420, -0.12837916709551257, CrossPlatformMachineEpsilon64)]
+ [InlineData(-0.96390253284987733, -0.41421356237309505, CrossPlatformMachineEpsilon64)]
+ [InlineData(-0.98383852942436249, -0.44269504088896341, CrossPlatformMachineEpsilon64)]
+ [InlineData(-0.97536797208363139, -0.42920367320510338, CrossPlatformMachineEpsilon64)]
+ [InlineData( 0.81376384817462330, 0.30258509299404568, CrossPlatformMachineEpsilon64)]
+ [InlineData( 0.77394268526670828, 0.28171817154095476, CrossPlatformMachineEpsilon64)]
+ [InlineData(-0.43030121700009227, -0.14159265358979324, CrossPlatformMachineEpsilon64)]
+ public static void AsinPiTest64(double value, double expectedResult, double allowedVariance)
+ {
+ AssertExtensions.Equal(-expectedResult, NFloat.AsinPi((NFloat)(-value)), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, NFloat.AsinPi((NFloat)(+value)), allowedVariance);
+ }
+
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))]
+ [InlineData( double.NaN, double.NaN, 0.0)]
+ [InlineData( 0.0, 0.0, 0.0)]
+ [InlineData( 1.5574077246549022, 0.31830988618379067, CrossPlatformMachineEpsilon64)]
+ [InlineData( 4.7754895402454188, 0.43429448190325183, CrossPlatformMachineEpsilon64)]
+ [InlineData( double.PositiveInfinity, 0.5, 0.0)]
+ [InlineData(-2.1850398632615190, -0.36338022763241866, CrossPlatformMachineEpsilon64)]
+ [InlineData(-1.4406084404920341, -0.30685281944005469, CrossPlatformMachineEpsilon64)]
+ [InlineData(-1.3136757077477542, -0.29289321881345248, CrossPlatformMachineEpsilon64)]
+ [InlineData(-0.79909939792801821, -0.21460183660255169, CrossPlatformMachineEpsilon64)]
+ [InlineData( 0.42670634433261806, 0.12837916709551257, CrossPlatformMachineEpsilon64)]
+ [InlineData( 3.6202185671074506, 0.41421356237309505, CrossPlatformMachineEpsilon64)]
+ [InlineData( 5.4945259425167300, 0.44269504088896341, CrossPlatformMachineEpsilon64)]
+ [InlineData(-4.4217522209161288, -0.42920367320510338, CrossPlatformMachineEpsilon64)]
+ [InlineData( 1.4001547140150527, 0.30258509299404568, CrossPlatformMachineEpsilon64)]
+ [InlineData(-1.2221646718190066, -0.28171817154095476, CrossPlatformMachineEpsilon64)]
+ [InlineData( 0.47669014603118892, 0.14159265358979324, CrossPlatformMachineEpsilon64)]
+ public static void AtanPiTest64(double value, double expectedResult, double allowedVariance)
+ {
+ AssertExtensions.Equal(-expectedResult, NFloat.AtanPi((NFloat)(-value)), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, NFloat.AtanPi((NFloat)(+value)), allowedVariance);
+ }
+
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))]
+ [InlineData(double.NaN, double.NaN, 0.0)]
+ [InlineData(0.0, 1.0, 0.0)]
+ [InlineData(0.31830988618379067, 0.54030230586813972, CrossPlatformMachineEpsilon64)] // value: (1 / pi)
+ [InlineData(0.43429448190325183, 0.20495719432643395, CrossPlatformMachineEpsilon64)] // value: (log10(e))
+ [InlineData(0.5, 0.0, 0.0)]
+ [InlineData(0.63661977236758134, -0.41614683654714239, CrossPlatformMachineEpsilon64)] // value: (2 / pi)
+ [InlineData(0.69314718055994531, -0.57023324876887755, CrossPlatformMachineEpsilon64)] // value: (ln(2))
+ [InlineData(0.70710678118654752, -0.60569986707881343, CrossPlatformMachineEpsilon64)] // value: (1 / sqrt(2))
+ [InlineData(0.78539816339744831, -0.78121189211048819, CrossPlatformMachineEpsilon64)] // value: (pi / 4)
+ [InlineData(1.0, -1.0, 0.0)]
+ [InlineData(1.1283791670955126, -0.91976499476851874, CrossPlatformMachineEpsilon64)] // value: (2 / sqrt(pi))
+ [InlineData(1.4142135623730950, -0.26625534204141549, CrossPlatformMachineEpsilon64)] // value: (sqrt(2))
+ [InlineData(1.4426950408889634, -0.17905794598427576, CrossPlatformMachineEpsilon64)] // value: (log2(e))
+ [InlineData(1.5, 0.0, 0.0)]
+ [InlineData(1.5707963267948966, 0.22058404074969809, CrossPlatformMachineEpsilon64)] // value: (pi / 2)
+ [InlineData(2.0, 1.0, 0.0)]
+ [InlineData(2.3025850929940457, 0.58119566361426737, CrossPlatformMachineEpsilon64)] // value: (ln(10))
+ [InlineData(2.5, 0.0, 0.0)]
+ [InlineData(2.7182818284590452, -0.63325565131482003, CrossPlatformMachineEpsilon64)] // value: (e)
+ [InlineData(3.0, -1.0, 0.0)]
+ [InlineData(3.1415926535897932, -0.90268536193307107, CrossPlatformMachineEpsilon64)] // value: (pi)
+ [InlineData(3.5, 0.0, 0.0)]
+ [InlineData(double.PositiveInfinity, double.NaN, 0.0)]
+ public static void CosPiTest64(double value, double expectedResult, double allowedVariance)
+ {
+ AssertExtensions.Equal(+expectedResult, NFloat.CosPi((NFloat)(-value)), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, NFloat.CosPi((NFloat)(+value)), allowedVariance);
+ }
+
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))]
+ [InlineData(double.NaN, double.NaN, 0.0)]
+ [InlineData(0.0, 0.0, 0.0)]
+ [InlineData(0.31830988618379067, 0.84147098480789651, CrossPlatformMachineEpsilon64)] // value: (1 / pi)
+ [InlineData(0.43429448190325183, 0.97877093770393305, CrossPlatformMachineEpsilon64)] // value: (log10(e))
+ [InlineData(0.5, 1.0, 0.0)]
+ [InlineData(0.63661977236758134, 0.90929742682568170, CrossPlatformMachineEpsilon64)] // value: (2 / pi)
+ [InlineData(0.69314718055994531, 0.82148283122563883, CrossPlatformMachineEpsilon64)] // value: (ln(2))
+ [InlineData(0.70710678118654752, 0.79569320156748087, CrossPlatformMachineEpsilon64)] // value: (1 / sqrt(2))
+ [InlineData(0.78539816339744831, 0.62426595263969903, CrossPlatformMachineEpsilon64)] // value: (pi / 4)
+ [InlineData(1.0, 0.0, 0.0)]
+ [InlineData(1.1283791670955126, -0.39246955856278420, CrossPlatformMachineEpsilon64)] // value: (2 / sqrt(pi))
+ [InlineData(1.4142135623730950, -0.96390253284987733, CrossPlatformMachineEpsilon64)] // value: (sqrt(2))
+ [InlineData(1.4426950408889634, -0.98383852942436249, CrossPlatformMachineEpsilon64)] // value: (log2(e))
+ [InlineData(1.5, -1.0, 0.0)]
+ [InlineData(1.5707963267948966, -0.97536797208363139, CrossPlatformMachineEpsilon64)] // value: (pi / 2)
+ [InlineData(2.0, 0.0, 0.0)]
+ [InlineData(2.3025850929940457, 0.81376384817462330, CrossPlatformMachineEpsilon64)] // value: (ln(10))
+ [InlineData(2.5, 1.0, 0.0)]
+ [InlineData(2.7182818284590452, 0.77394268526670828, CrossPlatformMachineEpsilon64)] // value: (e)
+ [InlineData(3.0, 0.0, 0.0)]
+ [InlineData(3.1415926535897932, -0.43030121700009227, CrossPlatformMachineEpsilon64)] // value: (pi)
+ [InlineData(3.5, -1.0, 0.0)]
+ [InlineData(double.PositiveInfinity, double.NaN, 0.0)]
+ public static void SinPiTest64(double value, double expectedResult, double allowedVariance)
+ {
+ AssertExtensions.Equal(-expectedResult, NFloat.SinPi((NFloat)(-value)), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, NFloat.SinPi((NFloat)(+value)), allowedVariance);
+ }
+
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))]
+ [InlineData(double.NaN, double.NaN, 0.0)]
+ [InlineData(0.0, 0.0, 0.0)]
+ [InlineData(0.31830988618379067, 1.5574077246549022, CrossPlatformMachineEpsilon64 * 10)] // value: (1 / pi)
+ [InlineData(0.43429448190325183, 4.7754895402454188, CrossPlatformMachineEpsilon64 * 10)] // value: (log10(e))
+ [InlineData(0.5, double.PositiveInfinity, 0.0)]
+ [InlineData(0.63661977236758134, -2.1850398632615190, CrossPlatformMachineEpsilon64 * 10)] // value: (2 / pi)
+ [InlineData(0.69314718055994531, -1.4406084404920341, CrossPlatformMachineEpsilon64 * 10)] // value: (ln(2))
+ [InlineData(0.70710678118654752, -1.3136757077477542, CrossPlatformMachineEpsilon64 * 10)] // value: (1 / sqrt(2))
+ [InlineData(0.78539816339744831, -0.79909939792801821, CrossPlatformMachineEpsilon64)] // value: (pi / 4)
+ [InlineData(1.0, -0.0, 0.0)]
+ [InlineData(1.1283791670955126, 0.42670634433261806, CrossPlatformMachineEpsilon64)] // value: (2 / sqrt(pi))
+ [InlineData(1.4142135623730950, 3.6202185671074506, CrossPlatformMachineEpsilon64 * 10)] // value: (sqrt(2))
+ [InlineData(1.4426950408889634, 5.4945259425167300, CrossPlatformMachineEpsilon64 * 10)] // value: (log2(e))
+ [InlineData(1.5, double.NegativeInfinity, 0.0)]
+ [InlineData(1.5707963267948966, -4.4217522209161288, CrossPlatformMachineEpsilon64 * 10)] // value: (pi / 2)
+ [InlineData(2.0, 0.0, 0.0)]
+ [InlineData(2.3025850929940457, 1.4001547140150527, CrossPlatformMachineEpsilon64 * 10)] // value: (ln(10))
+ [InlineData(2.5, double.PositiveInfinity, 0.0)]
+ [InlineData(2.7182818284590452, -1.2221646718190066, CrossPlatformMachineEpsilon64 * 10)] // value: (e)
+ [InlineData(3.0, -0.0, 0.0)]
+ [InlineData(3.1415926535897932, 0.47669014603118892, CrossPlatformMachineEpsilon64)] // value: (pi)
+ [InlineData(3.5, double.NegativeInfinity, 0.0)]
+ [InlineData(double.PositiveInfinity, double.NaN, 0.0)]
+ public static void TanPiTest64(double value, double expectedResult, double allowedVariance)
+ {
+ AssertExtensions.Equal(-expectedResult, NFloat.TanPi((NFloat)(-value)), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, NFloat.TanPi((NFloat)(+value)), allowedVariance);
+ }
}
}
diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs
index a26dbe17f6f67f..4d592b8f1f6284 100644
--- a/src/libraries/System.Runtime/ref/System.Runtime.cs
+++ b/src/libraries/System.Runtime/ref/System.Runtime.cs
@@ -2115,11 +2115,15 @@ public DivideByZeroException(string? message, System.Exception? innerException)
public static double Abs(double value) { throw null; }
public static double Acos(double x) { throw null; }
public static double Acosh(double x) { throw null; }
+ public static double AcosPi(double x) { throw null; }
public static double Asin(double x) { throw null; }
public static double Asinh(double x) { throw null; }
+ public static double AsinPi(double x) { throw null; }
public static double Atan(double x) { throw null; }
public static double Atan2(double y, double x) { throw null; }
+ public static double Atan2Pi(double y, double x) { throw null; }
public static double Atanh(double x) { throw null; }
+ public static double AtanPi(double x) { throw null; }
public static double BitDecrement(double x) { throw null; }
public static double BitIncrement(double x) { throw null; }
public static double Cbrt(double x) { throw null; }
@@ -2130,6 +2134,7 @@ public DivideByZeroException(string? message, System.Exception? innerException)
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 static double CosPi(double x) { throw null; }
public bool Equals(double obj) { throw null; }
public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; }
public static double Exp(double x) { throw null; }
@@ -2199,6 +2204,7 @@ public DivideByZeroException(string? message, System.Exception? innerException)
public static double Sin(double x) { throw null; }
public static (double Sin, double Cos) SinCos(double x) { throw null; }
public static double Sinh(double x) { throw null; }
+ public static double SinPi(double x) { throw null; }
public static double Sqrt(double x) { throw null; }
bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; }
byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; }
@@ -2248,6 +2254,7 @@ public DivideByZeroException(string? message, System.Exception? innerException)
static double System.Numerics.IUnaryPlusOperators.operator +(double value) { throw null; }
public static double Tan(double x) { throw null; }
public static double Tanh(double x) { throw null; }
+ public static double TanPi(double x) { throw null; }
public override string ToString() { throw null; }
public string ToString(System.IFormatProvider? provider) { throw null; }
public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; }
@@ -2738,11 +2745,15 @@ public GopherStyleUriParser() { }
public static System.Half Abs(System.Half value) { throw null; }
public static System.Half Acos(System.Half x) { throw null; }
public static System.Half Acosh(System.Half x) { throw null; }
+ public static System.Half AcosPi(System.Half x) { throw null; }
public static System.Half Asin(System.Half x) { throw null; }
public static System.Half Asinh(System.Half x) { throw null; }
+ public static System.Half AsinPi(System.Half x) { throw null; }
public static System.Half Atan(System.Half x) { throw null; }
public static System.Half Atan2(System.Half y, System.Half x) { throw null; }
+ public static System.Half Atan2Pi(System.Half y, System.Half x) { throw null; }
public static System.Half Atanh(System.Half x) { throw null; }
+ public static System.Half AtanPi(System.Half x) { throw null; }
public static System.Half BitDecrement(System.Half x) { throw null; }
public static System.Half BitIncrement(System.Half x) { throw null; }
public static System.Half Cbrt(System.Half x) { throw null; }
@@ -2753,6 +2764,7 @@ public GopherStyleUriParser() { }
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 static System.Half CosPi(System.Half x) { throw null; }
public bool Equals(System.Half other) { throw null; }
public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; }
public static System.Half Exp(System.Half x) { throw null; }
@@ -2890,6 +2902,7 @@ public GopherStyleUriParser() { }
public static System.Half Sin(System.Half x) { throw null; }
public static (System.Half Sin, System.Half Cos) SinCos(System.Half x) { throw null; }
public static System.Half Sinh(System.Half x) { throw null; }
+ public static System.Half SinPi(System.Half x) { throw null; }
public static System.Half Sqrt(System.Half x) { throw null; }
static System.Half System.Numerics.IBitwiseOperators.operator &(System.Half left, System.Half right) { throw null; }
static System.Half System.Numerics.IBitwiseOperators.operator |(System.Half left, System.Half right) { throw null; }
@@ -2915,6 +2928,7 @@ public GopherStyleUriParser() { }
static bool System.Numerics.INumberBase.TryConvertToTruncating(System.Half value, [System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] out TOther result) { throw null; }
public static System.Half Tan(System.Half x) { throw null; }
public static System.Half Tanh(System.Half x) { throw null; }
+ public static System.Half TanPi(System.Half x) { throw null; }
public override string ToString() { throw null; }
public string ToString(System.IFormatProvider? provider) { throw null; }
public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; }
@@ -4710,11 +4724,15 @@ public SerializableAttribute() { }
public static float Abs(float value) { throw null; }
public static float Acos(float x) { throw null; }
public static float Acosh(float x) { throw null; }
+ public static float AcosPi(float x) { throw null; }
public static float Asin(float x) { throw null; }
public static float Asinh(float x) { throw null; }
+ public static float AsinPi(float x) { throw null; }
public static float Atan(float x) { throw null; }
public static float Atan2(float y, float x) { throw null; }
+ public static float Atan2Pi(float y, float x) { throw null; }
public static float Atanh(float x) { throw null; }
+ public static float AtanPi(float x) { throw null; }
public static float BitDecrement(float x) { throw null; }
public static float BitIncrement(float x) { throw null; }
public static float Cbrt(float x) { throw null; }
@@ -4725,6 +4743,7 @@ public SerializableAttribute() { }
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 static float CosPi(float x) { throw null; }
public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; }
public bool Equals(float obj) { throw null; }
public static float Exp(float x) { throw null; }
@@ -4794,6 +4813,7 @@ public SerializableAttribute() { }
public static float Sin(float x) { throw null; }
public static (float Sin, float Cos) SinCos(float x) { throw null; }
public static float Sinh(float x) { throw null; }
+ public static float SinPi(float x) { throw null; }
public static float Sqrt(float x) { throw null; }
bool System.IConvertible.ToBoolean(System.IFormatProvider? provider) { throw null; }
byte System.IConvertible.ToByte(System.IFormatProvider? provider) { throw null; }
@@ -4843,6 +4863,7 @@ public SerializableAttribute() { }
static float System.Numerics.IUnaryPlusOperators.operator +(float value) { throw null; }
public static float Tan(float x) { throw null; }
public static float Tanh(float x) { throw null; }
+ public static float TanPi(float x) { throw null; }
public override string ToString() { throw null; }
public string ToString(System.IFormatProvider? provider) { throw null; }
public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string? format) { throw null; }
@@ -10544,13 +10565,20 @@ public partial interface ISubtractionOperators where TSe
public partial interface ITrigonometricFunctions where TSelf : System.Numerics.ITrigonometricFunctions, System.Numerics.INumberBase
{
static abstract TSelf Acos(TSelf x);
+ static abstract TSelf AcosPi(TSelf x);
static abstract TSelf Asin(TSelf x);
+ static abstract TSelf AsinPi(TSelf x);
static abstract TSelf Atan(TSelf x);
static abstract TSelf Atan2(TSelf y, TSelf x);
+ static abstract TSelf Atan2Pi(TSelf y, TSelf x);
+ static abstract TSelf AtanPi(TSelf x);
static abstract TSelf Cos(TSelf x);
+ static abstract TSelf CosPi(TSelf x);
static abstract TSelf Sin(TSelf x);
static abstract (TSelf Sin, TSelf Cos) SinCos(TSelf x);
+ static abstract TSelf SinPi(TSelf x);
static abstract TSelf Tan(TSelf x);
+ static abstract TSelf TanPi(TSelf x);
}
public partial interface IUnaryNegationOperators where TSelf : System.Numerics.IUnaryNegationOperators
{
diff --git a/src/libraries/System.Runtime/tests/System/DoubleTests.cs b/src/libraries/System.Runtime/tests/System/DoubleTests.cs
index d849aac40f553d..8e05c9c0df3dc8 100644
--- a/src/libraries/System.Runtime/tests/System/DoubleTests.cs
+++ b/src/libraries/System.Runtime/tests/System/DoubleTests.cs
@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Globalization;
using System.IO;
+using System.IO.Tests;
using System.Linq;
using Xunit;
@@ -1405,5 +1406,164 @@ public static void Log10P1Test(double value, double expectedResult, double allow
{
AssertExtensions.Equal(expectedResult, double.Log10P1(value), allowedVariance);
}
+
+ [Theory]
+ [InlineData( double.NaN, double.NaN, 0.0)]
+ [InlineData( 1.0, 0.0, 0.0)]
+ [InlineData( 0.54030230586813972, 0.31830988618379067, CrossPlatformMachineEpsilon)]
+ [InlineData( 0.20495719432643395, 0.43429448190325183, CrossPlatformMachineEpsilon)]
+ [InlineData( 0.0, 0.5, 0.0)]
+ [InlineData(-0.41614683654714239, 0.63661977236758134, CrossPlatformMachineEpsilon)]
+ [InlineData(-0.57023324876887755, 0.69314718055994531, CrossPlatformMachineEpsilon)]
+ [InlineData(-0.60569986707881343, 0.70710678118654752, CrossPlatformMachineEpsilon)]
+ [InlineData(-0.78121189211048819, 0.78539816339744831, CrossPlatformMachineEpsilon)]
+ [InlineData(-1.0, 1.0, 0.0)]
+ [InlineData(-0.91976499476851874, 0.87162083290448743, CrossPlatformMachineEpsilon)]
+ [InlineData(-0.26625534204141549, 0.58578643762690495, CrossPlatformMachineEpsilon)]
+ [InlineData(-0.17905794598427576, 0.55730495911103659, CrossPlatformMachineEpsilon)]
+ [InlineData( 0.22058404074969809, 0.42920367320510338, CrossPlatformMachineEpsilon)]
+ [InlineData( 0.58119566361426737, 0.30258509299404568, CrossPlatformMachineEpsilon)]
+ [InlineData(-0.63325565131482003, 0.71828182845904523, CrossPlatformMachineEpsilon)]
+ [InlineData(-0.90268536193307107, 0.85840734641020676, CrossPlatformMachineEpsilon)]
+ public static void AcosPiTest(double value, double expectedResult, double allowedVariance)
+ {
+ AssertExtensions.Equal(expectedResult, double.AcosPi(value), allowedVariance);
+ }
+
+ [Theory]
+ [InlineData( double.NaN, double.NaN, 0.0)]
+ [InlineData( 0.0, 0.0, 0.0)]
+ [InlineData( 0.84147098480789651, 0.31830988618379067, CrossPlatformMachineEpsilon)]
+ [InlineData( 0.97877093770393305, 0.43429448190325183, CrossPlatformMachineEpsilon)]
+ [InlineData( 1.0, 0.5, 0.0)]
+ [InlineData( 0.90929742682568170, 0.36338022763241866, CrossPlatformMachineEpsilon)]
+ [InlineData( 0.82148283122563883, 0.30685281944005469, CrossPlatformMachineEpsilon)]
+ [InlineData( 0.79569320156748087, 0.29289321881345248, CrossPlatformMachineEpsilon)]
+ [InlineData( 0.62426595263969903, 0.21460183660255169, CrossPlatformMachineEpsilon)]
+ [InlineData(-0.39246955856278420, -0.12837916709551257, CrossPlatformMachineEpsilon)]
+ [InlineData(-0.96390253284987733, -0.41421356237309505, CrossPlatformMachineEpsilon)]
+ [InlineData(-0.98383852942436249, -0.44269504088896341, CrossPlatformMachineEpsilon)]
+ [InlineData(-0.97536797208363139, -0.42920367320510338, CrossPlatformMachineEpsilon)]
+ [InlineData( 0.81376384817462330, 0.30258509299404568, CrossPlatformMachineEpsilon)]
+ [InlineData( 0.77394268526670828, 0.28171817154095476, CrossPlatformMachineEpsilon)]
+ [InlineData(-0.43030121700009227, -0.14159265358979324, CrossPlatformMachineEpsilon)]
+ public static void AsinPiTest(double value, double expectedResult, double allowedVariance)
+ {
+ AssertExtensions.Equal(-expectedResult, double.AsinPi(-value), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, double.AsinPi(+value), allowedVariance);
+ }
+
+ [Theory]
+ [InlineData( double.NaN, double.NaN, 0.0)]
+ [InlineData( 0.0, 0.0, 0.0)]
+ [InlineData( 1.5574077246549022, 0.31830988618379067, CrossPlatformMachineEpsilon)]
+ [InlineData( 4.7754895402454188, 0.43429448190325183, CrossPlatformMachineEpsilon)]
+ [InlineData( double.PositiveInfinity, 0.5, 0.0)]
+ [InlineData(-2.1850398632615190, -0.36338022763241866, CrossPlatformMachineEpsilon)]
+ [InlineData(-1.4406084404920341, -0.30685281944005469, CrossPlatformMachineEpsilon)]
+ [InlineData(-1.3136757077477542, -0.29289321881345248, CrossPlatformMachineEpsilon)]
+ [InlineData(-0.79909939792801821, -0.21460183660255169, CrossPlatformMachineEpsilon)]
+ [InlineData( 0.42670634433261806, 0.12837916709551257, CrossPlatformMachineEpsilon)]
+ [InlineData( 3.6202185671074506, 0.41421356237309505, CrossPlatformMachineEpsilon)]
+ [InlineData( 5.4945259425167300, 0.44269504088896341, CrossPlatformMachineEpsilon)]
+ [InlineData(-4.4217522209161288, -0.42920367320510338, CrossPlatformMachineEpsilon)]
+ [InlineData( 1.4001547140150527, 0.30258509299404568, CrossPlatformMachineEpsilon)]
+ [InlineData(-1.2221646718190066, -0.28171817154095476, CrossPlatformMachineEpsilon)]
+ [InlineData( 0.47669014603118892, 0.14159265358979324, CrossPlatformMachineEpsilon)]
+ public static void AtanPiTest(double value, double expectedResult, double allowedVariance)
+ {
+ AssertExtensions.Equal(-expectedResult, double.AtanPi(-value), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, double.AtanPi(+value), allowedVariance);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, double.NaN, 0.0)]
+ [InlineData(0.0, 1.0, 0.0)]
+ [InlineData(0.31830988618379067, 0.54030230586813972, CrossPlatformMachineEpsilon)] // value: (1 / pi)
+ [InlineData(0.43429448190325183, 0.20495719432643395, CrossPlatformMachineEpsilon)] // value: (log10(e))
+ [InlineData(0.5, 0.0, 0.0)]
+ [InlineData(0.63661977236758134, -0.41614683654714239, CrossPlatformMachineEpsilon)] // value: (2 / pi)
+ [InlineData(0.69314718055994531, -0.57023324876887755, CrossPlatformMachineEpsilon)] // value: (ln(2))
+ [InlineData(0.70710678118654752, -0.60569986707881343, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2))
+ [InlineData(0.78539816339744831, -0.78121189211048819, CrossPlatformMachineEpsilon)] // value: (pi / 4)
+ [InlineData(1.0, -1.0, 0.0)]
+ [InlineData(1.1283791670955126, -0.91976499476851874, CrossPlatformMachineEpsilon)] // value: (2 / sqrt(pi))
+ [InlineData(1.4142135623730950, -0.26625534204141549, CrossPlatformMachineEpsilon)] // value: (sqrt(2))
+ [InlineData(1.4426950408889634, -0.17905794598427576, CrossPlatformMachineEpsilon)] // value: (log2(e))
+ [InlineData(1.5, 0.0, 0.0)]
+ [InlineData(1.5707963267948966, 0.22058404074969809, CrossPlatformMachineEpsilon)] // value: (pi / 2)
+ [InlineData(2.0, 1.0, 0.0)]
+ [InlineData(2.3025850929940457, 0.58119566361426737, CrossPlatformMachineEpsilon)] // value: (ln(10))
+ [InlineData(2.5, 0.0, 0.0)]
+ [InlineData(2.7182818284590452, -0.63325565131482003, CrossPlatformMachineEpsilon)] // value: (e)
+ [InlineData(3.0, -1.0, 0.0)]
+ [InlineData(3.1415926535897932, -0.90268536193307107, CrossPlatformMachineEpsilon)] // value: (pi)
+ [InlineData(3.5, 0.0, 0.0)]
+ [InlineData(double.PositiveInfinity, double.NaN, 0.0)]
+ public static void CosPiTest(double value, double expectedResult, double allowedVariance)
+ {
+ AssertExtensions.Equal(+expectedResult, double.CosPi(-value), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, double.CosPi(+value), allowedVariance);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, double.NaN, 0.0)]
+ [InlineData(0.0, 0.0, 0.0)]
+ [InlineData(0.31830988618379067, 0.84147098480789651, CrossPlatformMachineEpsilon)] // value: (1 / pi)
+ [InlineData(0.43429448190325183, 0.97877093770393305, CrossPlatformMachineEpsilon)] // value: (log10(e))
+ [InlineData(0.5, 1.0, 0.0)]
+ [InlineData(0.63661977236758134, 0.90929742682568170, CrossPlatformMachineEpsilon)] // value: (2 / pi)
+ [InlineData(0.69314718055994531, 0.82148283122563883, CrossPlatformMachineEpsilon)] // value: (ln(2))
+ [InlineData(0.70710678118654752, 0.79569320156748087, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2))
+ [InlineData(0.78539816339744831, 0.62426595263969903, CrossPlatformMachineEpsilon)] // value: (pi / 4)
+ [InlineData(1.0, 0.0, 0.0)]
+ [InlineData(1.1283791670955126, -0.39246955856278420, CrossPlatformMachineEpsilon)] // value: (2 / sqrt(pi))
+ [InlineData(1.4142135623730950, -0.96390253284987733, CrossPlatformMachineEpsilon)] // value: (sqrt(2))
+ [InlineData(1.4426950408889634, -0.98383852942436249, CrossPlatformMachineEpsilon)] // value: (log2(e))
+ [InlineData(1.5, -1.0, 0.0)]
+ [InlineData(1.5707963267948966, -0.97536797208363139, CrossPlatformMachineEpsilon)] // value: (pi / 2)
+ [InlineData(2.0, 0.0, 0.0)]
+ [InlineData(2.3025850929940457, 0.81376384817462330, CrossPlatformMachineEpsilon)] // value: (ln(10))
+ [InlineData(2.5, 1.0, 0.0)]
+ [InlineData(2.7182818284590452, 0.77394268526670828, CrossPlatformMachineEpsilon)] // value: (e)
+ [InlineData(3.0, 0.0, 0.0)]
+ [InlineData(3.1415926535897932, -0.43030121700009227, CrossPlatformMachineEpsilon)] // value: (pi)
+ [InlineData(3.5, -1.0, 0.0)]
+ [InlineData(double.PositiveInfinity, double.NaN, 0.0)]
+ public static void SinPiTest(double value, double expectedResult, double allowedVariance)
+ {
+ AssertExtensions.Equal(-expectedResult, double.SinPi(-value), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, double.SinPi(+value), allowedVariance);
+ }
+
+ [Theory]
+ [InlineData(double.NaN, double.NaN, 0.0)]
+ [InlineData(0.0, 0.0, 0.0)]
+ [InlineData(0.31830988618379067, 1.5574077246549022, CrossPlatformMachineEpsilon * 10)] // value: (1 / pi)
+ [InlineData(0.43429448190325183, 4.7754895402454188, CrossPlatformMachineEpsilon * 10)] // value: (log10(e))
+ [InlineData(0.5, double.PositiveInfinity, 0.0)]
+ [InlineData(0.63661977236758134, -2.1850398632615190, CrossPlatformMachineEpsilon * 10)] // value: (2 / pi)
+ [InlineData(0.69314718055994531, -1.4406084404920341, CrossPlatformMachineEpsilon * 10)] // value: (ln(2))
+ [InlineData(0.70710678118654752, -1.3136757077477542, CrossPlatformMachineEpsilon * 10)] // value: (1 / sqrt(2))
+ [InlineData(0.78539816339744831, -0.79909939792801821, CrossPlatformMachineEpsilon)] // value: (pi / 4)
+ [InlineData(1.0, -0.0, 0.0)]
+ [InlineData(1.1283791670955126, 0.42670634433261806, CrossPlatformMachineEpsilon)] // value: (2 / sqrt(pi))
+ [InlineData(1.4142135623730950, 3.6202185671074506, CrossPlatformMachineEpsilon * 10)] // value: (sqrt(2))
+ [InlineData(1.4426950408889634, 5.4945259425167300, CrossPlatformMachineEpsilon * 10)] // value: (log2(e))
+ [InlineData(1.5, double.NegativeInfinity, 0.0)]
+ [InlineData(1.5707963267948966, -4.4217522209161288, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2)
+ [InlineData(2.0, 0.0, 0.0)]
+ [InlineData(2.3025850929940457, 1.4001547140150527, CrossPlatformMachineEpsilon * 10)] // value: (ln(10))
+ [InlineData(2.5, double.PositiveInfinity, 0.0)]
+ [InlineData(2.7182818284590452, -1.2221646718190066, CrossPlatformMachineEpsilon * 10)] // value: (e)
+ [InlineData(3.0, -0.0, 0.0)]
+ [InlineData(3.1415926535897932, 0.47669014603118892, CrossPlatformMachineEpsilon)] // value: (pi)
+ [InlineData(3.5, double.NegativeInfinity, 0.0)]
+ [InlineData(double.PositiveInfinity, double.NaN, 0.0)]
+ public static void TanPiTest(double value, double expectedResult, double allowedVariance)
+ {
+ AssertExtensions.Equal(-expectedResult, double.TanPi(-value), allowedVariance);
+ AssertExtensions.Equal(+expectedResult, double.TanPi(+value), allowedVariance);
+ }
}
}
diff --git a/src/libraries/System.Runtime/tests/System/HalfTests.cs b/src/libraries/System.Runtime/tests/System/HalfTests.cs
index 994536e410800f..a8ea447c1f37d6 100644
--- a/src/libraries/System.Runtime/tests/System/HalfTests.cs
+++ b/src/libraries/System.Runtime/tests/System/HalfTests.cs
@@ -1544,14 +1544,14 @@ public static IEnumerable