diff --git a/src/libraries/System.Private.CoreLib/src/System/Double.cs b/src/libraries/System.Private.CoreLib/src/System/Double.cs index ad0c042c6e503f..bf83f532e08104 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Double.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Double.cs @@ -620,20 +620,20 @@ public static bool IsPow2(double value) /// public static double Exp(double x) => Math.Exp(x); - // /// - // public static double ExpM1(double x) => Math.ExpM1(x); + /// + public static double ExpM1(double x) => Math.Exp(x) - 1; - // /// - // public static double Exp2(double x) => Math.Exp2(x); + /// + public static double Exp2(double x) => Math.Pow(2, x); - // /// - // public static double Exp2M1(double x) => Math.Exp2M1(x); + /// + public static double Exp2M1(double x) => Math.Pow(2, x) - 1; - // /// - // public static double Exp10(double x) => Math.Exp10(x); + /// + public static double Exp10(double x) => Math.Pow(10, x); - // /// - // public static double Exp10M1(double x) => Math.Exp10M1(x); + /// + public static double Exp10M1(double x) => Math.Pow(10, x) - 1; // // IFloatingPoint @@ -911,17 +911,17 @@ public static double MinNumber(double x, double y) /// public static double Log(double x, double newBase) => Math.Log(x, newBase); - /// - public static double Log10(double x) => Math.Log10(x); + /// + public static double LogP1(double x) => Math.Log(x + 1); - // /// - // public static double LogP1(double x) => Math.LogP1(x); + /// + public static double Log2P1(double x) => Math.Log2(x + 1); - // /// - // public static double Log2P1(double x) => Math.Log2P1(x); + /// + public static double Log10(double x) => Math.Log10(x); - // /// - // public static double Log10P1(double x) => Math.Log10P1(x); + /// + public static double Log10P1(double x) => Math.Log10(x + 1); // // IMinMaxValue @@ -940,8 +940,6 @@ public static double MinNumber(double x, double y) /// static double IModulusOperators.operator %(double left, double right) => left % right; - // static checked double IModulusOperators.operator %(double left, double right) => checked(left % right); - // // IMultiplicativeIdentity // diff --git a/src/libraries/System.Private.CoreLib/src/System/Half.cs b/src/libraries/System.Private.CoreLib/src/System/Half.cs index 9117913cf13847..c34bce2e1e3097 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Half.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Half.cs @@ -841,20 +841,20 @@ public static bool IsPow2(Half value) /// public static Half Exp(Half x) => (Half)MathF.Exp((float)x); - // /// - // public static Half ExpM1(Half x) => (Half)MathF.ExpM1((float)x); + /// + public static Half ExpM1(Half x) => (Half)float.ExpM1((float)x); - // /// - // public static Half Exp2(Half x) => (Half)MathF.Exp2((float)x); + /// + public static Half Exp2(Half x) => (Half)float.Exp2((float)x); - // /// - // public static Half Exp2M1(Half x) => (Half)MathF.Exp2M1((float)x); + /// + public static Half Exp2M1(Half x) => (Half)float.Exp2M1((float)x); - // /// - // public static Half Exp10(Half x) => (Half)MathF.Exp10((float)x); + /// + public static Half Exp10(Half x) => (Half)float.Exp10((float)x); - // /// - // public static Half Exp10M1(Half x) => (Half)MathF.Exp10M1((float)x); + /// + public static Half Exp10M1(Half x) => (Half)float.Exp10M1((float)x); // // IFloatingPoint @@ -1128,14 +1128,14 @@ public static Half MinNumber(Half x, Half y) /// public static Half Log10(Half x) => (Half)MathF.Log10((float)x); - // /// - // public static Half LogP1(Half x) => (Half)MathF.LogP1((float)x); + /// + public static Half LogP1(Half x) => (Half)float.LogP1((float)x); - // /// - // public static Half Log2P1(Half x) => (Half)MathF.Log2P1((float)x); + /// + public static Half Log2P1(Half x) => (Half)float.Log2P1((float)x); - // /// - // public static Half Log10P1(Half x) => (Half)MathF.Log10P1((float)x); + /// + public static Half Log10P1(Half x) => (Half)float.Log10P1((float)x); // // IModulusOperators diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IExponentialFunctions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IExponentialFunctions.cs index 122fc8626e200b..bc5a08ae7057c1 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IExponentialFunctions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IExponentialFunctions.cs @@ -10,14 +10,32 @@ public interface IExponentialFunctions { /// Computes E raised to a given power. /// The power to which E is raised. - /// E raised to the power of . + /// E static abstract TSelf Exp(TSelf x); - // The following methods are approved but not yet implemented in the libraries - // * static abstract TSelf ExpM1(TSelf x); - // * static abstract TSelf Exp2(TSelf x); - // * static abstract TSelf Exp2M1(TSelf x); - // * static abstract TSelf Exp10(TSelf x); - // * static abstract TSelf Exp10M1(TSelf x); + /// Computes E raised to a given power and subtracts one. + /// The power to which E is raised. + /// E - 1 + static abstract TSelf ExpM1(TSelf x); + + /// Computes 2 raised to a given power. + /// The power to which 2 is raised. + /// 2 + static abstract TSelf Exp2(TSelf x); + + /// Computes 2 raised to a given power and subtracts one. + /// The power to which 2 is raised. + /// 2 - 1 + static abstract TSelf Exp2M1(TSelf x); + + /// Computes 10 raised to a given power. + /// The power to which 10 is raised. + /// 10 + static abstract TSelf Exp10(TSelf x); + + /// Computes 10 raised to a given power and subtracts one. + /// The power to which 10 is raised. + /// 10 - 1 + static abstract TSelf Exp10M1(TSelf x); } } diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/ILogarithmicFunctions.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/ILogarithmicFunctions.cs index 1dd07003948c5e..c27e1230ccf288 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Numerics/ILogarithmicFunctions.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/ILogarithmicFunctions.cs @@ -8,30 +8,40 @@ namespace System.Numerics public interface ILogarithmicFunctions where TSelf : ILogarithmicFunctions { - /// Computes the natural (base-E logarithm of a value. + /// Computes the natural (base-E) logarithm of a value. /// The value whose natural logarithm is to be computed. - /// The natural logarithm of . + /// loge() static abstract TSelf Log(TSelf x); /// Computes the logarithm of a value in the specified base. /// The value whose logarithm is to be computed. /// The base in which the logarithm is to be computed. - /// The base- logarithm of . + /// log() static abstract TSelf Log(TSelf x, TSelf newBase); + /// Computes the natural (base-E) logarithm of a value plus one. + /// The value to which one is added before computing the natural logarithm. + /// loge( + 1) + static abstract TSelf LogP1(TSelf x); + /// Computes the base-2 logarithm of a value. /// The value whose base-2 logarithm is to be computed. - /// The base-2 logarithm of . + /// log2() static abstract TSelf Log2(TSelf x); + /// Computes the base-2 logarithm of a value plus one. + /// The value to which one is added before computing the base-2 logarithm. + /// log2( + 1) + static abstract TSelf Log2P1(TSelf x); + /// Computes the base-10 logarithm of a value. /// The value whose base-10 logarithm is to be computed. - /// The base-10 logarithm of . + /// log10() static abstract TSelf Log10(TSelf x); - // The following methods are approved but not yet implemented in the libraries - // * static abstract TSelf LogP1(TSelf x); - // * static abstract TSelf Log2P1(TSelf x); - // * static abstract TSelf Log10P1(TSelf x); + /// Computes the base-10 logarithm of a value plus one. + /// The value to which one is added before computing the base-10 logarithm. + /// log10( + 1) + static abstract TSelf Log10P1(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 240e2f1478842a..aa5a5502a4cb0e 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 @@ -820,20 +820,20 @@ public int CompareTo(object? obj) /// public static NFloat Exp(NFloat x) => new NFloat(NativeType.Exp(x._value)); - // /// - // public static NFloat ExpM1(NFloat x) => new NFloat(NativeType.ExpM1(x._value)); + /// + public static NFloat ExpM1(NFloat x) => new NFloat(NativeType.ExpM1(x._value)); - // /// - // public static NFloat Exp2(NFloat x) => new NFloat(NativeType.Exp2(x._value)); + /// + public static NFloat Exp2(NFloat x) => new NFloat(NativeType.Exp2(x._value)); - // /// - // public static NFloat Exp2M1(NFloat x) => new NFloat(NativeType.Exp2M1(x._value)); + /// + public static NFloat Exp2M1(NFloat x) => new NFloat(NativeType.Exp2M1(x._value)); - // /// - // public static NFloat Exp10(NFloat x) => new NFloat(NativeType.Exp10(x._value))(x); + /// + public static NFloat Exp10(NFloat x) => new NFloat(NativeType.Exp10(x._value)); - // /// - // public static NFloat Exp10M1(NFloat x) => new NFloat(NativeType.Exp10M1(x._value)); + /// + public static NFloat Exp10M1(NFloat x) => new NFloat(NativeType.Exp10M1(x._value)); // // IFloatingPoint @@ -1021,17 +1021,17 @@ bool IFloatingPoint.TryWriteSignificandLittleEndian(Span destinati /// public static NFloat Log(NFloat x, NFloat newBase) => new NFloat(NativeType.Log(x._value, newBase._value)); - /// - public static NFloat Log10(NFloat x) => new NFloat(NativeType.Log10(x._value)); + /// + public static NFloat LogP1(NFloat x) => new NFloat(NativeType.LogP1(x._value)); - // /// - // public static NFloat LogP1(NFloat x) => new NFloat(NativeType.LogP1(x._value)); + /// + public static NFloat Log2P1(NFloat x) => new NFloat(NativeType.Log2P1(x._value)); - // /// - // public static NFloat Log2P1(NFloat x) => new NFloat(NativeType.Log2P1(x._value)); + /// + public static NFloat Log10(NFloat x) => new NFloat(NativeType.Log10(x._value)); - // /// - // public static NFloat Log10P1(NFloat x) => new NFloat(NativeType.Log10P1(x._value)); + /// + public static NFloat Log10P1(NFloat x) => new NFloat(NativeType.Log10P1(x._value)); // // IMultiplicativeIdentity diff --git a/src/libraries/System.Private.CoreLib/src/System/Single.cs b/src/libraries/System.Private.CoreLib/src/System/Single.cs index cac2b3b68e7913..958ae554981027 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Single.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Single.cs @@ -615,20 +615,20 @@ public static bool IsPow2(float value) /// public static float Exp(float x) => MathF.Exp(x); - // /// - // public static float ExpM1(float x) => MathF.ExpM1(x); + /// + public static float ExpM1(float x) => MathF.Exp(x) - 1; - // /// - // public static float Exp2(float x) => MathF.Exp2(x); + /// + public static float Exp2(float x) => MathF.Pow(2, x); - // /// - // public static float Exp2M1(float x) => MathF.Exp2M1(x); + /// + public static float Exp2M1(float x) => MathF.Pow(2, x) - 1; - // /// - // public static float Exp10(float x) => MathF.Exp10(x); + /// + public static float Exp10(float x) => MathF.Pow(10, x); - // /// - // public static float Exp10M1(float x) => MathF.Exp10M1(x); + /// + public static float Exp10M1(float x) => MathF.Pow(10, x) - 1; // // IFloatingPoint @@ -906,17 +906,17 @@ public static float MinNumber(float x, float y) /// public static float Log(float x, float newBase) => MathF.Log(x, newBase); + /// + public static float LogP1(float x) => MathF.Log(x + 1); + /// public static float Log10(float x) => MathF.Log10(x); - // /// - // public static float LogP1(float x) => MathF.LogP1(x); - - // /// - // public static float Log2P1(float x) => MathF.Log2P1(x); + /// + public static float Log2P1(float x) => MathF.Log2(x + 1); - // /// - // public static float Log10P1(float x) => MathF.Log10P1(x); + /// + public static float Log10P1(float x) => MathF.Log10(x + 1); // // IMinMaxValue @@ -935,8 +935,6 @@ public static float MinNumber(float x, float y) /// static float IModulusOperators.operator %(float left, float right) => left % right; - // static checked float IModulusOperators.operator %(float left, float right) => checked(left % right); - // // IMultiplicativeIdentity // 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 70db265b8dcebb..0897a7938d20cb 100644 --- a/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs +++ b/src/libraries/System.Runtime.InteropServices/ref/System.Runtime.InteropServices.cs @@ -943,6 +943,11 @@ public static void Free(void* ptr) { } 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; } + public static System.Runtime.InteropServices.NFloat Exp10(System.Runtime.InteropServices.NFloat x) { throw null; } + public static System.Runtime.InteropServices.NFloat Exp10M1(System.Runtime.InteropServices.NFloat x) { throw null; } + public static System.Runtime.InteropServices.NFloat Exp2(System.Runtime.InteropServices.NFloat x) { throw null; } + public static System.Runtime.InteropServices.NFloat Exp2M1(System.Runtime.InteropServices.NFloat x) { throw null; } + public static System.Runtime.InteropServices.NFloat ExpM1(System.Runtime.InteropServices.NFloat x) { throw null; } 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; } @@ -960,7 +965,10 @@ public static void Free(void* ptr) { } public static System.Runtime.InteropServices.NFloat Log(System.Runtime.InteropServices.NFloat x) { throw null; } public static System.Runtime.InteropServices.NFloat Log(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat newBase) { throw null; } public static System.Runtime.InteropServices.NFloat Log10(System.Runtime.InteropServices.NFloat x) { throw null; } + public static System.Runtime.InteropServices.NFloat Log10P1(System.Runtime.InteropServices.NFloat x) { throw null; } public static System.Runtime.InteropServices.NFloat Log2(System.Runtime.InteropServices.NFloat value) { throw null; } + public static System.Runtime.InteropServices.NFloat Log2P1(System.Runtime.InteropServices.NFloat x) { throw null; } + public static System.Runtime.InteropServices.NFloat LogP1(System.Runtime.InteropServices.NFloat x) { throw null; } public static System.Runtime.InteropServices.NFloat Max(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat MaxMagnitude(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { throw null; } public static System.Runtime.InteropServices.NFloat MaxMagnitudeNumber(System.Runtime.InteropServices.NFloat x, System.Runtime.InteropServices.NFloat y) { 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 52df5080182bc5..cd3a5d1b2487c5 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 @@ -14,6 +14,25 @@ namespace System.Runtime.InteropServices.Tests { public class NFloatTests { + // The tests themselves will take CrossPlatformMachineEpsilon## and adjust it according to the expected result + // so that the delta used for comparison will compare the most significant digits and ignore + // any digits that are outside the single or double precision range (6-9 or 15-17 digits). + // + // For example, a test with an expect result in the format of 0.xxxxxxxxx will use + // CrossPlatformMachineEpsilon## for the variance, while an expected result in the format of 0.0xxxxxxxxx + // will use CrossPlatformMachineEpsilon## / 10 and expected result in the format of x.xxxxxx will + // use CrossPlatformMachineEpsilon## * 10. + + // binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this + // is slightly too accurate when writing tests meant to run against libm implementations + // for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. + private const float CrossPlatformMachineEpsilon32 = 4.76837158e-07f; + + // binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this + // is slightly too accurate when writing tests meant to run against libm implementations + // for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. + private const double CrossPlatformMachineEpsilon64 = 8.8817841970012523e-16; + [Fact] public void Ctor_Empty() { @@ -1102,5 +1121,641 @@ public static void MinNumberTest64(double x, double y, double expectedResult) { AssertExtensions.Equal(expectedResult, NFloat.MinNumber((NFloat)x, (NFloat)y), 0.0); } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))] + [InlineData( float.NegativeInfinity, -1.0f, 0.0f)] + [InlineData(-3.14159265f, -0.956786082f, CrossPlatformMachineEpsilon32)] // value: -(pi) + [InlineData(-2.71828183f, -0.934011964f, CrossPlatformMachineEpsilon32)] // value: -(e) + [InlineData(-2.30258509f, -0.9f, CrossPlatformMachineEpsilon32)] // value: -(ln(10)) + [InlineData(-1.57079633f, -0.792120424f, CrossPlatformMachineEpsilon32)] // value: -(pi / 2) + [InlineData(-1.44269504f, -0.763709912f, CrossPlatformMachineEpsilon32)] // value: -(log2(e)) + [InlineData(-1.41421356f, -0.756883266f, CrossPlatformMachineEpsilon32)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, -0.676442736f, CrossPlatformMachineEpsilon32)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, -0.632120559f, CrossPlatformMachineEpsilon32)] + [InlineData(-0.785398163f, -0.544061872f, CrossPlatformMachineEpsilon32)] // value: -(pi / 4) + [InlineData(-0.707106781f, -0.506931309f, CrossPlatformMachineEpsilon32)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, -0.5f, CrossPlatformMachineEpsilon32)] // value: -(ln(2)) + [InlineData(-0.636619772f, -0.470922192f, CrossPlatformMachineEpsilon32)] // value: -(2 / pi) + [InlineData(-0.434294482f, -0.352278515f, CrossPlatformMachineEpsilon32)] // value: -(log10(e)) + [InlineData(-0.318309886f, -0.272622651f, CrossPlatformMachineEpsilon32)] // value: -(1 / pi) + [InlineData(-0.0f, 0.0f, 0.0f)] + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData( 0.0f, 0.0f, 0.0f)] + [InlineData( 0.318309886f, 0.374802227f, CrossPlatformMachineEpsilon32)] // value: (1 / pi) + [InlineData( 0.434294482f, 0.543873444f, CrossPlatformMachineEpsilon32)] // value: (log10(e)) + [InlineData( 0.636619772f, 0.890081165f, CrossPlatformMachineEpsilon32)] // value: (2 / pi) + [InlineData( 0.693147181f, 1.0f, CrossPlatformMachineEpsilon32 * 10)] // value: (ln(2)) + [InlineData( 0.707106781f, 1.02811498f, CrossPlatformMachineEpsilon32 * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.785398163f, 1.19328005f, CrossPlatformMachineEpsilon32 * 10)] // value: (pi / 4) + [InlineData( 1.0f, 1.71828183f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 1.12837917f, 2.09064302f, CrossPlatformMachineEpsilon32 * 10)] // value: (2 / sqrt(pi)) + [InlineData( 1.41421356f, 3.11325038f, CrossPlatformMachineEpsilon32 * 10)] // value: (sqrt(2)) + [InlineData( 1.44269504f, 3.23208611f, CrossPlatformMachineEpsilon32 * 10)] // value: (log2(e)) + [InlineData( 1.57079633f, 3.81047738f, CrossPlatformMachineEpsilon32 * 10)] // value: (pi / 2) + [InlineData( 2.30258509f, 9.0f, CrossPlatformMachineEpsilon32 * 10)] // value: (ln(10)) + [InlineData( 2.71828183f, 14.1542622f, CrossPlatformMachineEpsilon32 * 100)] // value: (e) + [InlineData( 3.14159265f, 22.1406926f, CrossPlatformMachineEpsilon32 * 100)] // value: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void ExpM1Test32(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, (float)NFloat.ExpM1(value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))] + [InlineData( float.NegativeInfinity, 0.0f, 0.0f)] + [InlineData(-3.14159265f, 0.113314732f, CrossPlatformMachineEpsilon32)] // value: -(pi) + [InlineData(-2.71828183f, 0.151955223f, CrossPlatformMachineEpsilon32)] // value: -(e) + [InlineData(-2.30258509f, 0.202699566f, CrossPlatformMachineEpsilon32)] // value: -(ln(10)) + [InlineData(-1.57079633f, 0.336622537f, CrossPlatformMachineEpsilon32)] // value: -(pi / 2) + [InlineData(-1.44269504f, 0.367879441f, CrossPlatformMachineEpsilon32)] // value: -(log2(e)) + [InlineData(-1.41421356f, 0.375214227f, CrossPlatformMachineEpsilon32)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, 0.457429347f, CrossPlatformMachineEpsilon32)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, 0.5f, CrossPlatformMachineEpsilon32)] + [InlineData(-0.785398163f, 0.580191810f, CrossPlatformMachineEpsilon32)] // value: -(pi / 4) + [InlineData(-0.707106781f, 0.612547327f, CrossPlatformMachineEpsilon32)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, 0.618503138f, CrossPlatformMachineEpsilon32)] // value: -(ln(2)) + [InlineData(-0.636619772f, 0.643218242f, CrossPlatformMachineEpsilon32)] // value: -(2 / pi) + [InlineData(-0.434294482f, 0.740055574f, CrossPlatformMachineEpsilon32)] // value: -(log10(e)) + [InlineData(-0.318309886f, 0.802008879f, CrossPlatformMachineEpsilon32)] // value: -(1 / pi) + [InlineData(-0.0f, 1.0f, 0.0f)] + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData( 0.0f, 1.0f, 0.0f)] + [InlineData( 0.318309886f, 1.24686899f, CrossPlatformMachineEpsilon32 * 10)] // value: (1 / pi) + [InlineData( 0.434294482f, 1.35124987f, CrossPlatformMachineEpsilon32 * 10)] // value: (log10(e)) + [InlineData( 0.636619772f, 1.55468228f, CrossPlatformMachineEpsilon32 * 10)] // value: (2 / pi) + [InlineData( 0.693147181f, 1.61680667f, CrossPlatformMachineEpsilon32 * 10)] // value: (ln(2)) + [InlineData( 0.707106781f, 1.63252692f, CrossPlatformMachineEpsilon32 * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.785398163f, 1.72356793f, CrossPlatformMachineEpsilon32 * 10)] // value: (pi / 4) + [InlineData( 1.0f, 2.0, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 1.12837917f, 2.18612996f, CrossPlatformMachineEpsilon32 * 10)] // value: (2 / sqrt(pi)) + [InlineData( 1.41421356f, 2.66514414f, CrossPlatformMachineEpsilon32 * 10)] // value: (sqrt(2)) + [InlineData( 1.44269504f, 2.71828183f, CrossPlatformMachineEpsilon32 * 10)] // value: (log2(e)) + [InlineData( 1.57079633f, 2.97068642f, CrossPlatformMachineEpsilon32 * 10)] // value: (pi / 2) + [InlineData( 2.30258509f, 4.93340967f, CrossPlatformMachineEpsilon32 * 10)] // value: (ln(10)) + [InlineData( 2.71828183f, 6.58088599f, CrossPlatformMachineEpsilon32 * 10)] // value: (e) + [InlineData( 3.14159265f, 8.82497783f, CrossPlatformMachineEpsilon32 * 10)] // value: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Exp2Test32(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, (float)NFloat.Exp2(value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))] + [InlineData( float.NegativeInfinity, -1.0f, 0.0f)] + [InlineData(-3.14159265f, -0.886685268f, CrossPlatformMachineEpsilon32)] // value: -(pi) + [InlineData(-2.71828183f, -0.848044777f, CrossPlatformMachineEpsilon32)] // value: -(e) + [InlineData(-2.30258509f, -0.797300434f, CrossPlatformMachineEpsilon32)] // value: -(ln(10)) + [InlineData(-1.57079633f, -0.663377463f, CrossPlatformMachineEpsilon32)] // value: -(pi / 2) + [InlineData(-1.44269504f, -0.632120559f, CrossPlatformMachineEpsilon32)] // value: -(log2(e)) + [InlineData(-1.41421356f, -0.624785773f, CrossPlatformMachineEpsilon32)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, -0.542570653f, CrossPlatformMachineEpsilon32)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, -0.5f, CrossPlatformMachineEpsilon32)] + [InlineData(-0.785398163f, -0.419808190f, CrossPlatformMachineEpsilon32)] // value: -(pi / 4) + [InlineData(-0.707106781f, -0.387452673f, CrossPlatformMachineEpsilon32)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, -0.381496862f, CrossPlatformMachineEpsilon32)] // value: -(ln(2)) + [InlineData(-0.636619772f, -0.356781758f, CrossPlatformMachineEpsilon32)] // value: -(2 / pi) + [InlineData(-0.434294482f, -0.259944426f, CrossPlatformMachineEpsilon32)] // value: -(log10(e)) + [InlineData(-0.318309886f, -0.197991121f, CrossPlatformMachineEpsilon32)] // value: -(1 / pi) + [InlineData(-0.0f, 0.0f, 0.0f)] + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData( 0.0f, 0.0f, 0.0f)] + [InlineData( 0.318309886f, 0.246868989f, CrossPlatformMachineEpsilon32)] // value: (1 / pi) + [InlineData( 0.434294482f, 0.351249873f, CrossPlatformMachineEpsilon32)] // value: (log10(e)) + [InlineData( 0.636619772f, 0.554682275f, CrossPlatformMachineEpsilon32)] // value: (2 / pi) + [InlineData( 0.693147181f, 0.616806672f, CrossPlatformMachineEpsilon32)] // value: (ln(2)) + [InlineData( 0.707106781f, 0.632526919f, CrossPlatformMachineEpsilon32)] // value: (1 / sqrt(2)) + [InlineData( 0.785398163f, 0.723567934f, CrossPlatformMachineEpsilon32)] // value: (pi / 4) + [InlineData( 1.0f, 1.0f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 1.12837917f, 1.18612996f, CrossPlatformMachineEpsilon32 * 10)] // value: (2 / sqrt(pi)) + [InlineData( 1.41421356f, 1.66514414f, CrossPlatformMachineEpsilon32 * 10)] // value: (sqrt(2)) + [InlineData( 1.44269504f, 1.71828183f, CrossPlatformMachineEpsilon32 * 10)] // value: (log2(e)) + [InlineData( 1.57079633f, 1.97068642f, CrossPlatformMachineEpsilon32 * 10)] // value: (pi / 2) + [InlineData( 2.30258509f, 3.93340967f, CrossPlatformMachineEpsilon32 * 10)] // value: (ln(10)) + [InlineData( 2.71828183f, 5.58088599f, CrossPlatformMachineEpsilon32 * 10)] // value: (e) + [InlineData( 3.14159265f, 7.82497783f, CrossPlatformMachineEpsilon32 * 10)] // value: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Exp2M1Test32(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, (float)NFloat.Exp2M1(value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))] + [InlineData( float.NegativeInfinity, 0.0, 0.0f)] + [InlineData(-3.14159265f, 0.000721784159f, CrossPlatformMachineEpsilon32 / 1000)] // value: -(pi) + [InlineData(-2.71828183f, 0.00191301410f, CrossPlatformMachineEpsilon32 / 100)] // value: -(e) + [InlineData(-2.30258509f, 0.00498212830f, CrossPlatformMachineEpsilon32 / 100)] // value: -(ln(10)) + [InlineData(-1.57079633f, 0.0268660410f, CrossPlatformMachineEpsilon32 / 10)] // value: -(pi / 2) + [InlineData(-1.44269504f, 0.0360831928f, CrossPlatformMachineEpsilon32 / 10)] // value: -(log2(e)) + [InlineData(-1.41421356f, 0.0385288847f, CrossPlatformMachineEpsilon32 / 10)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, 0.0744082059f, CrossPlatformMachineEpsilon32 / 10)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, 0.1f, CrossPlatformMachineEpsilon32)] + [InlineData(-0.785398163f, 0.163908636f, CrossPlatformMachineEpsilon32)] // value: -(pi / 4) + [InlineData(-0.707106781f, 0.196287760f, CrossPlatformMachineEpsilon32)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, 0.202699566f, CrossPlatformMachineEpsilon32)] // value: -(ln(2)) + [InlineData(-0.636619772f, 0.230876765f, CrossPlatformMachineEpsilon32)] // value: -(2 / pi) + [InlineData(-0.434294482f, 0.367879441f, CrossPlatformMachineEpsilon32)] // value: -(log10(e)) + [InlineData(-0.318309886f, 0.480496373f, CrossPlatformMachineEpsilon32)] // value: -(1 / pi) + [InlineData(-0.0f, 1.0f, 0.0f)] + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData( 0.0f, 1.0f, 0.0f)] + [InlineData( 0.318309886f, 2.08118116f, CrossPlatformMachineEpsilon32 * 10)] // value: (1 / pi) + [InlineData( 0.434294482f, 2.71828183f, CrossPlatformMachineEpsilon32 * 10)] // value: (log10(e)) + [InlineData( 0.636619772f, 4.33131503f, CrossPlatformMachineEpsilon32 * 10)] // value: (2 / pi) + [InlineData( 0.693147181f, 4.93340967f, CrossPlatformMachineEpsilon32 * 10)] // value: (ln(2)) + [InlineData( 0.707106781f, 5.09456117f, CrossPlatformMachineEpsilon32 * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.785398163f, 6.10095980f, CrossPlatformMachineEpsilon32 * 10)] // value: (pi / 4) + [InlineData( 1.0f, 10.0f, CrossPlatformMachineEpsilon32 * 100)] + [InlineData( 1.12837917f, 13.4393779f, CrossPlatformMachineEpsilon32 * 100)] // value: (2 / sqrt(pi)) + [InlineData( 1.41421356f, 25.9545535f, CrossPlatformMachineEpsilon32 * 100)] // value: (sqrt(2)) + [InlineData( 1.44269504f, 27.7137338f, CrossPlatformMachineEpsilon32 * 100)] // value: (log2(e)) + [InlineData( 1.57079633f, 37.2217105f, CrossPlatformMachineEpsilon32 * 100)] // value: (pi / 2) + [InlineData( 2.30258509f, 200.717432f, CrossPlatformMachineEpsilon32 * 1000)] // value: (ln(10)) + [InlineData( 2.71828183f, 522.735300f, CrossPlatformMachineEpsilon32 * 1000)] // value: (e) + [InlineData( 3.14159265f, 1385.45573f, CrossPlatformMachineEpsilon32 * 10000)] // value: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Exp10Test32(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, (float)NFloat.Exp10(value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))] + [InlineData( float.NegativeInfinity, -1.0f, 0.0f)] + [InlineData(-3.14159265f, -0.999278216f, CrossPlatformMachineEpsilon32)] // value: -(pi) + [InlineData(-2.71828183f, -0.998086986f, CrossPlatformMachineEpsilon32)] // value: -(e) + [InlineData(-2.30258509f, -0.995017872f, CrossPlatformMachineEpsilon32)] // value: -(ln(10)) + [InlineData(-1.57079633f, -0.973133959f, CrossPlatformMachineEpsilon32)] // value: -(pi / 2) + [InlineData(-1.44269504f, -0.963916807f, CrossPlatformMachineEpsilon32)] // value: -(log2(e)) + [InlineData(-1.41421356f, -0.961471115f, CrossPlatformMachineEpsilon32)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, -0.925591794f, CrossPlatformMachineEpsilon32)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, -0.9f, CrossPlatformMachineEpsilon32)] + [InlineData(-0.785398163f, -0.836091364f, CrossPlatformMachineEpsilon32)] // value: -(pi / 4) + [InlineData(-0.707106781f, -0.803712240f, CrossPlatformMachineEpsilon32)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, -0.797300434f, CrossPlatformMachineEpsilon32)] // value: -(ln(2)) + [InlineData(-0.636619772f, -0.769123235f, CrossPlatformMachineEpsilon32)] // value: -(2 / pi) + [InlineData(-0.434294482f, -0.632120559f, CrossPlatformMachineEpsilon32)] // value: -(log10(e)) + [InlineData(-0.318309886f, -0.519503627f, CrossPlatformMachineEpsilon32)] // value: -(1 / pi) + [InlineData(-0.0f, 0.0f, 0.0f)] + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData( 0.0f, 0.0f, 0.0f)] + [InlineData( 0.318309886f, 1.08118116f, CrossPlatformMachineEpsilon32 * 10)] // value: (1 / pi) + [InlineData( 0.434294482f, 1.71828183f, CrossPlatformMachineEpsilon32 * 10)] // value: (log10(e)) + [InlineData( 0.636619772f, 3.33131503f, CrossPlatformMachineEpsilon32 * 10)] // value: (2 / pi) + [InlineData( 0.693147181f, 3.93340967f, CrossPlatformMachineEpsilon32 * 10)] // value: (ln(2)) + [InlineData( 0.707106781f, 4.09456117f, CrossPlatformMachineEpsilon32 * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.785398163f, 5.10095980f, CrossPlatformMachineEpsilon32 * 10)] // value: (pi / 4) + [InlineData( 1.0f, 9.0, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 1.12837917f, 12.4393779f, CrossPlatformMachineEpsilon32 * 100)] // value: (2 / sqrt(pi)) + [InlineData( 1.41421356f, 24.9545535f, CrossPlatformMachineEpsilon32 * 100)] // value: (sqrt(2)) + [InlineData( 1.44269504f, 26.7137338f, CrossPlatformMachineEpsilon32 * 100)] // value: (log2(e)) + [InlineData( 1.57079633f, 36.2217105f, CrossPlatformMachineEpsilon32 * 100)] // value: (pi / 2) + [InlineData( 2.30258509f, 199.717432f, CrossPlatformMachineEpsilon32 * 1000)] // value: (ln(10)) + [InlineData( 2.71828183f, 521.735300f, CrossPlatformMachineEpsilon32 * 1000)] // value: (e) + [InlineData( 3.14159265f, 1384.45573f, CrossPlatformMachineEpsilon32 * 10000)] // value: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0)] + public static void Exp10M1Test32(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, (float)NFloat.Exp10M1(value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))] + [InlineData( float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(-3.14159265f, float.NaN, 0.0f)] // value: -(pi) + [InlineData(-2.71828183f, float.NaN, 0.0f)] // value: -(e) + [InlineData(-1.41421356f, float.NaN, 0.0f)] // value: -(sqrt(2)) + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData(-1.0f, float.NegativeInfinity, 0.0f)] + [InlineData(-0.956786082f, -3.14159265f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(pi) + [InlineData(-0.934011964f, -2.71828183f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(e) + [InlineData(-0.9f, -2.30258509f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(ln(10)) + [InlineData(-0.792120424f, -1.57079633f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(pi / 2) + [InlineData(-0.763709912f, -1.44269504f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(log2(e)) + [InlineData(-0.756883266f, -1.41421356f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(sqrt(2)) + [InlineData(-0.676442736f, -1.12837917f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(-0.632120559f, -1.0f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData(-0.544061872f, -0.785398163f, CrossPlatformMachineEpsilon32)] // expected: -(pi / 4) + [InlineData(-0.506931309f, -0.707106781f, CrossPlatformMachineEpsilon32)] // expected: -(1 / sqrt(2)) + [InlineData(-0.5f, -0.693147181f, CrossPlatformMachineEpsilon32)] // expected: -(ln(2)) + [InlineData(-0.470922192f, -0.636619772f, CrossPlatformMachineEpsilon32)] // expected: -(2 / pi) + [InlineData(-0.0f, 0.0f, 0.0f)] + [InlineData( 0.0f, 0.0f, 0.0f)] + [InlineData( 0.374802227f, 0.318309886f, CrossPlatformMachineEpsilon32)] // expected: (1 / pi) + [InlineData( 0.543873444f, 0.434294482f, CrossPlatformMachineEpsilon32)] // expected: (log10(e)) + [InlineData( 0.890081165f, 0.636619772f, CrossPlatformMachineEpsilon32)] // expected: (2 / pi) + [InlineData( 1.0f, 0.693147181f, CrossPlatformMachineEpsilon32)] // expected: (ln(2)) + [InlineData( 1.02811498f, 0.707106781f, CrossPlatformMachineEpsilon32)] // expected: (1 / sqrt(2)) + [InlineData( 1.19328005f, 0.785398163f, CrossPlatformMachineEpsilon32)] // expected: (pi / 4) + [InlineData( 1.71828183f, 1.0f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 2.09064302f, 1.12837917f, CrossPlatformMachineEpsilon32 * 10)] // expected: (2 / sqrt(pi)) + [InlineData( 3.11325038f, 1.41421356f, CrossPlatformMachineEpsilon32 * 10)] // expected: (sqrt(2)) + [InlineData( 3.23208611f, 1.44269504f, CrossPlatformMachineEpsilon32 * 10)] // expected: (log2(e)) + [InlineData( 3.81047738f, 1.57079633f, CrossPlatformMachineEpsilon32 * 10)] // expected: (pi / 2) + [InlineData( 9.0f, 2.30258509f, CrossPlatformMachineEpsilon32 * 10)] // expected: (ln(10)) + [InlineData( 14.1542622f, 2.71828183f, CrossPlatformMachineEpsilon32 * 10)] // expected: (e) + [InlineData( 22.1406926f, 3.14159265f, CrossPlatformMachineEpsilon32 * 10)] // expected: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void LogP1Test32(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, (float)NFloat.LogP1(value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))] + [InlineData( float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData(-1.0f, float.NegativeInfinity, 0.0f)] + [InlineData(-0.886685268f, -3.14159265f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(pi) + [InlineData(-0.848044777f, -2.71828183f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(e) + [InlineData(-0.797300434f, -2.30258509f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(ln(10)) + [InlineData(-0.663377463f, -1.57079633f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(pi / 2) + [InlineData(-0.632120559f, -1.44269504f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(log2(e)) + [InlineData(-0.624785773f, -1.41421356f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(sqrt(2)) + [InlineData(-0.542570653f, -1.12837917f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(-0.5f, -1.0f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData(-0.419808190f, -0.785398163f, CrossPlatformMachineEpsilon32)] // expected: -(pi / 4) + [InlineData(-0.387452673f, -0.707106781f, CrossPlatformMachineEpsilon32)] // expected: -(1 / sqrt(2)) + [InlineData(-0.381496862f, -0.693147181f, CrossPlatformMachineEpsilon32)] // expected: -(ln(2)) + [InlineData(-0.356781758f, -0.636619772f, CrossPlatformMachineEpsilon32)] // expected: -(2 / pi) + [InlineData(-0.259944426f, -0.434294482f, CrossPlatformMachineEpsilon32)] // expected: -(log10(e)) + [InlineData(-0.197991121f, -0.318309886f, CrossPlatformMachineEpsilon32)] // expected: -(1 / pi) + [InlineData(-0.0f, 0.0f, 0.0f)] + [InlineData( 0.0f, 0.0f, 0.0f)] + [InlineData( 0.246868989f, 0.318309886f, CrossPlatformMachineEpsilon32)] // expected: (1 / pi) + [InlineData( 0.351249873f, 0.434294482f, CrossPlatformMachineEpsilon32)] // expected: (log10(e)) + [InlineData( 0.554682275f, 0.636619772f, CrossPlatformMachineEpsilon32)] // expected: (2 / pi) + [InlineData( 0.616806672f, 0.693147181f, CrossPlatformMachineEpsilon32)] // expected: (ln(2)) + [InlineData( 0.632526919f, 0.707106781f, CrossPlatformMachineEpsilon32)] // expected: (1 / sqrt(2)) + [InlineData( 0.723567934f, 0.785398163f, CrossPlatformMachineEpsilon32)] // expected: (pi / 4) + [InlineData( 1.0f, 1.0f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 1.18612996f, 1.12837917f, CrossPlatformMachineEpsilon32 * 10)] // expected: (2 / sqrt(pi)) + [InlineData( 1.66514414f, 1.41421356f, CrossPlatformMachineEpsilon32 * 10)] // expected: (sqrt(2)) + [InlineData( 1.71828183f, 1.44269504f, CrossPlatformMachineEpsilon32 * 10)] // expected: (log2(e)) + [InlineData( 1.97068642f, 1.57079633f, CrossPlatformMachineEpsilon32 * 10)] // expected: (pi / 2) + [InlineData( 3.93340967f, 2.30258509f, CrossPlatformMachineEpsilon32 * 10)] // expected: (ln(10)) + [InlineData( 5.58088599f, 2.71828183f, CrossPlatformMachineEpsilon32 * 10)] // expected: (e) + [InlineData( 7.82497783f, 3.14159265f, CrossPlatformMachineEpsilon32 * 10)] // expected: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Log2P1Test32(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, (float)NFloat.Log2P1(value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is32BitProcess))] + [InlineData( float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(-3.14159265f, float.NaN, 0.0f)] // value: -(pi) + [InlineData(-2.71828183f, float.NaN, 0.0f)] // value: -(e) + [InlineData(-1.41421356f, float.NaN, 0.0f)] // value: -(sqrt(2)) + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData(-1.0f, float.NegativeInfinity, 0.0f)] + [InlineData(-0.998086986f, -2.71828183f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(e) + [InlineData(-0.995017872f, -2.30258509f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(ln(10)) + [InlineData(-0.973133959f, -1.57079633f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(pi / 2) + [InlineData(-0.963916807f, -1.44269504f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(log2(e)) + [InlineData(-0.961471115f, -1.41421356f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(sqrt(2)) + [InlineData(-0.925591794f, -1.12837917f, CrossPlatformMachineEpsilon32 * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(-0.9f, -1.0f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData(-0.836091364f, -0.785398163f, CrossPlatformMachineEpsilon32)] // expected: -(pi / 4) + [InlineData(-0.803712240f, -0.707106781f, CrossPlatformMachineEpsilon32)] // expected: -(1 / sqrt(2)) + [InlineData(-0.797300434f, -0.693147181f, CrossPlatformMachineEpsilon32)] // expected: -(ln(2)) + [InlineData(-0.769123235f, -0.636619772f, CrossPlatformMachineEpsilon32)] // expected: -(2 / pi) + [InlineData(-0.632120559f, -0.434294482f, CrossPlatformMachineEpsilon32)] // expected: -(log10(e)) + [InlineData(-0.519503627f, -0.318309886f, CrossPlatformMachineEpsilon32)] // expected: -(1 / pi) + [InlineData(-0.0f, 0.0f, 0.0f)] + [InlineData( 0.0f, 0.0f, 0.0f)] + [InlineData( 1.08118116f, 0.318309886f, CrossPlatformMachineEpsilon32)] // expected: (1 / pi) + [InlineData( 1.71828183f, 0.434294482f, CrossPlatformMachineEpsilon32)] // expected: (log10(e)) value: (e) + [InlineData( 3.33131503f, 0.636619772f, CrossPlatformMachineEpsilon32)] // expected: (2 / pi) + [InlineData( 3.93340967f, 0.693147181f, CrossPlatformMachineEpsilon32)] // expected: (ln(2)) + [InlineData( 4.09456117f, 0.707106781f, CrossPlatformMachineEpsilon32)] // expected: (1 / sqrt(2)) + [InlineData( 5.10095980f, 0.785398163f, CrossPlatformMachineEpsilon32)] // expected: (pi / 4) + [InlineData( 9.0f, 1.0f, CrossPlatformMachineEpsilon32 * 10)] + [InlineData( 12.4393779f, 1.12837917f, CrossPlatformMachineEpsilon32 * 10)] // expected: (2 / sqrt(pi)) + [InlineData( 24.9545535f, 1.41421356f, CrossPlatformMachineEpsilon32 * 10)] // expected: (sqrt(2)) + [InlineData( 26.7137338f, 1.44269504f, CrossPlatformMachineEpsilon32 * 10)] // expected: (log2(e)) + [InlineData( 36.2217105f, 1.57079633f, CrossPlatformMachineEpsilon32 * 10)] // expected: (pi / 2) + [InlineData( 199.717432f, 2.30258509f, CrossPlatformMachineEpsilon32 * 10)] // expected: (ln(10)) + [InlineData( 521.735300f, 2.71828183f, CrossPlatformMachineEpsilon32 * 10)] // expected: (e) + [InlineData( 1384.45573f, 3.14159265f, CrossPlatformMachineEpsilon32 * 10)] // expected: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Log10P1Test32(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, (float)NFloat.Log10P1(value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] + [InlineData( double.NegativeInfinity, -1.0, 0.0)] + [InlineData(-3.1415926535897932, -0.95678608173622775, CrossPlatformMachineEpsilon64)] // value: -(pi) + [InlineData(-2.7182818284590452, -0.93401196415468746, CrossPlatformMachineEpsilon64)] // value: -(e) + [InlineData(-2.3025850929940457, -0.9, CrossPlatformMachineEpsilon64)] // value: -(ln(10)) + [InlineData(-1.5707963267948966, -0.79212042364923809, CrossPlatformMachineEpsilon64)] // value: -(pi / 2) + [InlineData(-1.4426950408889634, -0.76370991165547730, CrossPlatformMachineEpsilon64)] // value: -(log2(e)) + [InlineData(-1.4142135623730950, -0.75688326556578579, CrossPlatformMachineEpsilon64)] // value: -(sqrt(2)) + [InlineData(-1.1283791670955126, -0.67644273609692890, CrossPlatformMachineEpsilon64)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0, -0.63212055882855768, CrossPlatformMachineEpsilon64)] + [InlineData(-0.78539816339744831, -0.54406187223400376, CrossPlatformMachineEpsilon64)] // value: -(pi / 4) + [InlineData(-0.70710678118654752, -0.50693130860476021, CrossPlatformMachineEpsilon64)] // value: -(1 / sqrt(2)) + [InlineData(-0.69314718055994531, -0.5, CrossPlatformMachineEpsilon64)] // value: -(ln(2)) + [InlineData(-0.63661977236758134, -0.47092219173226465, CrossPlatformMachineEpsilon64)] // value: -(2 / pi) + [InlineData(-0.43429448190325183, -0.35227851485819935, CrossPlatformMachineEpsilon64)] // value: -(log10(e)) + [InlineData(-0.31830988618379067, -0.27262265070478353, CrossPlatformMachineEpsilon64)] // value: -(1 / pi) + [InlineData(-0.0, 0.0, 0.0)] + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData( 0.0, 0.0, 0.0)] + [InlineData( 0.31830988618379067, 0.37480222743935863, CrossPlatformMachineEpsilon64)] // value: (1 / pi) + [InlineData( 0.43429448190325183, 0.54387344397118114, CrossPlatformMachineEpsilon64)] // value: (log10(e)) + [InlineData( 0.63661977236758134, 0.89008116457222198, CrossPlatformMachineEpsilon64)] // value: (2 / pi) + [InlineData( 0.69314718055994531, 1.0, CrossPlatformMachineEpsilon64 * 10)] // value: (ln(2)) + [InlineData( 0.70710678118654752, 1.0281149816474725, CrossPlatformMachineEpsilon64 * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.78539816339744831, 1.1932800507380155, CrossPlatformMachineEpsilon64 * 10)] // value: (pi / 4) + [InlineData( 1.0, 1.7182818284590452, CrossPlatformMachineEpsilon64 * 10)] + [InlineData( 1.1283791670955126, 2.0906430223107976, CrossPlatformMachineEpsilon64 * 10)] // value: (2 / sqrt(pi)) + [InlineData( 1.4142135623730950, 3.1132503787829275, CrossPlatformMachineEpsilon64 * 10)] // value: (sqrt(2)) + [InlineData( 1.4426950408889634, 3.2320861065570819, CrossPlatformMachineEpsilon64 * 10)] // value: (log2(e)) + [InlineData( 1.5707963267948966, 3.8104773809653517, CrossPlatformMachineEpsilon64 * 10)] // value: (pi / 2) + [InlineData( 2.3025850929940457, 9.0, CrossPlatformMachineEpsilon64 * 10)] // value: (ln(10)) + [InlineData( 2.7182818284590452, 14.154262241479264, CrossPlatformMachineEpsilon64 * 100)] // value: (e) + [InlineData( 3.1415926535897932, 22.140692632779269, CrossPlatformMachineEpsilon64 * 100)] // value: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void ExpM1Test64(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, NFloat.ExpM1((NFloat)value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] + [InlineData( double.NegativeInfinity, 0.0, 0.0)] + [InlineData(-3.1415926535897932, 0.11331473229676087, CrossPlatformMachineEpsilon64)] // value: -(pi) + [InlineData(-2.7182818284590452, 0.15195522325791297, CrossPlatformMachineEpsilon64)] // value: -(e) + [InlineData(-2.3025850929940457, 0.20269956628651730, CrossPlatformMachineEpsilon64)] // value: -(ln(10)) + [InlineData(-1.5707963267948966, 0.33662253682241906, CrossPlatformMachineEpsilon64)] // value: -(pi / 2) + [InlineData(-1.4426950408889634, 0.36787944117144232, CrossPlatformMachineEpsilon64)] // value: -(log2(e)) + [InlineData(-1.4142135623730950, 0.37521422724648177, CrossPlatformMachineEpsilon64)] // value: -(sqrt(2)) + [InlineData(-1.1283791670955126, 0.45742934732229695, CrossPlatformMachineEpsilon64)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0, 0.5, CrossPlatformMachineEpsilon64)] + [InlineData(-0.78539816339744831, 0.58019181037172444, CrossPlatformMachineEpsilon64)] // value: -(pi / 4) + [InlineData(-0.70710678118654752, 0.61254732653606592, CrossPlatformMachineEpsilon64)] // value: -(1 / sqrt(2)) + [InlineData(-0.69314718055994531, 0.61850313780157598, CrossPlatformMachineEpsilon64)] // value: -(ln(2)) + [InlineData(-0.63661977236758134, 0.64321824193300488, CrossPlatformMachineEpsilon64)] // value: -(2 / pi) + [InlineData(-0.43429448190325183, 0.74005557395545179, CrossPlatformMachineEpsilon64)] // value: -(log10(e)) + [InlineData(-0.31830988618379067, 0.80200887896145195, CrossPlatformMachineEpsilon64)] // value: -(1 / pi) + [InlineData(-0.0, 1.0, 0.0)] + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData( 0.0, 1.0, 0.0)] + [InlineData( 0.31830988618379067, 1.2468689889006383, CrossPlatformMachineEpsilon64 * 10)] // value: (1 / pi) + [InlineData( 0.43429448190325183, 1.3512498725672672, CrossPlatformMachineEpsilon64 * 10)] // value: (log10(e)) + [InlineData( 0.63661977236758134, 1.5546822754821001, CrossPlatformMachineEpsilon64 * 10)] // value: (2 / pi) + [InlineData( 0.69314718055994531, 1.6168066722416747, CrossPlatformMachineEpsilon64 * 10)] // value: (ln(2)) + [InlineData( 0.70710678118654752, 1.6325269194381528, CrossPlatformMachineEpsilon64 * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.78539816339744831, 1.7235679341273495, CrossPlatformMachineEpsilon64 * 10)] // value: (pi / 4) + [InlineData( 1.0, 2.0, CrossPlatformMachineEpsilon64 * 10)] + [InlineData( 1.1283791670955126, 2.1861299583286618, CrossPlatformMachineEpsilon64 * 10)] // value: (2 / sqrt(pi)) + [InlineData( 1.4142135623730950, 2.6651441426902252, CrossPlatformMachineEpsilon64 * 10)] // value: (sqrt(2)) + [InlineData( 1.4426950408889634, 2.7182818284590452, CrossPlatformMachineEpsilon64 * 10)] // value: (log2(e)) + [InlineData( 1.5707963267948966, 2.9706864235520193, CrossPlatformMachineEpsilon64 * 10)] // value: (pi / 2) + [InlineData( 2.3025850929940457, 4.9334096679145963, CrossPlatformMachineEpsilon64 * 10)] // value: (ln(10)) + [InlineData( 2.7182818284590452, 6.5808859910179210, CrossPlatformMachineEpsilon64 * 10)] // value: (e) + [InlineData( 3.1415926535897932, 8.8249778270762876, CrossPlatformMachineEpsilon64 * 10)] // value: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Exp2Test64(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, NFloat.Exp2((NFloat)value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] + [InlineData( double.NegativeInfinity, -1.0, 0.0)] + [InlineData(-3.1415926535897932, -0.88668526770323913, CrossPlatformMachineEpsilon64)] // value: -(pi) + [InlineData(-2.7182818284590452, -0.84804477674208703, CrossPlatformMachineEpsilon64)] // value: -(e) + [InlineData(-2.3025850929940457, -0.79730043371348270, CrossPlatformMachineEpsilon64)] // value: -(ln(10)) + [InlineData(-1.5707963267948966, -0.66337746317758094, CrossPlatformMachineEpsilon64)] // value: -(pi / 2) + [InlineData(-1.4426950408889634, -0.63212055882855768, CrossPlatformMachineEpsilon64)] // value: -(log2(e)) + [InlineData(-1.4142135623730950, -0.62478577275351823, CrossPlatformMachineEpsilon64)] // value: -(sqrt(2)) + [InlineData(-1.1283791670955126, -0.54257065267770305, CrossPlatformMachineEpsilon64)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0, -0.5, CrossPlatformMachineEpsilon64)] + [InlineData(-0.78539816339744831, -0.41980818962827556, CrossPlatformMachineEpsilon64)] // value: -(pi / 4) + [InlineData(-0.70710678118654752, -0.38745267346393408, CrossPlatformMachineEpsilon64)] // value: -(1 / sqrt(2)) + [InlineData(-0.69314718055994531, -0.38149686219842402, CrossPlatformMachineEpsilon64)] // value: -(ln(2)) + [InlineData(-0.63661977236758134, -0.35678175806699512, CrossPlatformMachineEpsilon64)] // value: -(2 / pi) + [InlineData(-0.43429448190325183, -0.25994442604454821, CrossPlatformMachineEpsilon64)] // value: -(log10(e)) + [InlineData(-0.31830988618379067, -0.19799112103854805, CrossPlatformMachineEpsilon64)] // value: -(1 / pi) + [InlineData(-0.0, 0.0, 0.0)] + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData( 0.0, 0.0, 0.0)] + [InlineData( 0.31830988618379067, 0.24686898890063831, CrossPlatformMachineEpsilon64)] // value: (1 / pi) + [InlineData( 0.43429448190325183, 0.35124987256726717, CrossPlatformMachineEpsilon64)] // value: (log10(e)) + [InlineData( 0.63661977236758134, 0.55468227548210009, CrossPlatformMachineEpsilon64)] // value: (2 / pi) + [InlineData( 0.69314718055994531, 0.61680667224167466, CrossPlatformMachineEpsilon64)] // value: (ln(2)) + [InlineData( 0.70710678118654752, 0.63252691943815284, CrossPlatformMachineEpsilon64)] // value: (1 / sqrt(2)) + [InlineData( 0.78539816339744831, 0.72356793412734949, CrossPlatformMachineEpsilon64)] // value: (pi / 4) + [InlineData( 1.0, 1.0, CrossPlatformMachineEpsilon64 * 10)] + [InlineData( 1.1283791670955126, 1.1861299583286618, CrossPlatformMachineEpsilon64 * 10)] // value: (2 / sqrt(pi)) + [InlineData( 1.4142135623730950, 1.6651441426902252, CrossPlatformMachineEpsilon64 * 10)] // value: (sqrt(2)) + [InlineData( 1.4426950408889634, 1.7182818284590452, CrossPlatformMachineEpsilon64 * 10)] // value: (log2(e)) + [InlineData( 1.5707963267948966, 1.9706864235520193, CrossPlatformMachineEpsilon64 * 10)] // value: (pi / 2) + [InlineData( 2.3025850929940457, 3.9334096679145963, CrossPlatformMachineEpsilon64 * 10)] // value: (ln(10)) + [InlineData( 2.7182818284590452, 5.5808859910179210, CrossPlatformMachineEpsilon64 * 10)] // value: (e) + [InlineData( 3.1415926535897932, 7.8249778270762876, CrossPlatformMachineEpsilon64 * 10)] // value: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Exp2M1Test64(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, NFloat.Exp2M1((NFloat)value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] + [InlineData( double.NegativeInfinity, 0.0, 0.0)] + [InlineData(-3.1415926535897932, 0.00072178415907472774, CrossPlatformMachineEpsilon64 / 1000)] // value: -(pi) + [InlineData(-2.7182818284590452, 0.0019130141022243176, CrossPlatformMachineEpsilon64 / 100)] // value: -(e) + [InlineData(-2.3025850929940457, 0.0049821282964407206, CrossPlatformMachineEpsilon64 / 100)] // value: -(ln(10)) + [InlineData(-1.5707963267948966, 0.026866041001136132, CrossPlatformMachineEpsilon64 / 10)] // value: -(pi / 2) + [InlineData(-1.4426950408889634, 0.036083192820787210, CrossPlatformMachineEpsilon64 / 10)] // value: -(log2(e)) + [InlineData(-1.4142135623730950, 0.038528884700322026, CrossPlatformMachineEpsilon64 / 10)] // value: -(sqrt(2)) + [InlineData(-1.1283791670955126, 0.074408205860642723, CrossPlatformMachineEpsilon64 / 10)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0, 0.1, CrossPlatformMachineEpsilon64)] + [InlineData(-0.78539816339744831, 0.16390863613957665, CrossPlatformMachineEpsilon64)] // value: -(pi / 4) + [InlineData(-0.70710678118654752, 0.19628775993505562, CrossPlatformMachineEpsilon64)] // value: -(1 / sqrt(2)) + [InlineData(-0.69314718055994531, 0.20269956628651730, CrossPlatformMachineEpsilon64)] // value: -(ln(2)) + [InlineData(-0.63661977236758134, 0.23087676451600055, CrossPlatformMachineEpsilon64)] // value: -(2 / pi) + [InlineData(-0.43429448190325183, 0.36787944117144232, CrossPlatformMachineEpsilon64)] // value: -(log10(e)) + [InlineData(-0.31830988618379067, 0.48049637305186868, CrossPlatformMachineEpsilon64)] // value: -(1 / pi) + [InlineData(-0.0, 1.0, 0.0)] + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData( 0.0, 1.0, 0.0)] + [InlineData( 0.31830988618379067, 2.0811811619898573, CrossPlatformMachineEpsilon64 * 10)] // value: (1 / pi) + [InlineData( 0.43429448190325183, 2.7182818284590452, CrossPlatformMachineEpsilon64 * 10)] // value: (log10(e)) + [InlineData( 0.63661977236758134, 4.3313150290214525, CrossPlatformMachineEpsilon64 * 10)] // value: (2 / pi) + [InlineData( 0.69314718055994531, 4.9334096679145963, CrossPlatformMachineEpsilon64 * 10)] // value: (ln(2)) + [InlineData( 0.70710678118654752, 5.0945611704512962, CrossPlatformMachineEpsilon64 * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.78539816339744831, 6.1009598002416937, CrossPlatformMachineEpsilon64 * 10)] // value: (pi / 4) + [InlineData( 1.0, 10.0, CrossPlatformMachineEpsilon64 * 100)] + [InlineData( 1.1283791670955126, 13.439377934644401, CrossPlatformMachineEpsilon64 * 100)] // value: (2 / sqrt(pi)) + [InlineData( 1.4142135623730950, 25.954553519470081, CrossPlatformMachineEpsilon64 * 100)] // value: (sqrt(2)) + [InlineData( 1.4426950408889634, 27.713733786437790, CrossPlatformMachineEpsilon64 * 100)] // value: (log2(e)) + [InlineData( 1.5707963267948966, 37.221710484165167, CrossPlatformMachineEpsilon64 * 100)] // value: (pi / 2) + [InlineData( 2.3025850929940457, 200.71743249053009, CrossPlatformMachineEpsilon64 * 1000)] // value: (ln(10)) + [InlineData( 2.7182818284590452, 522.73529967043665, CrossPlatformMachineEpsilon64 * 1000)] // value: (e) + [InlineData( 3.1415926535897932, 1385.4557313670111, CrossPlatformMachineEpsilon64 * 10000)] // value: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Exp10Test64(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, NFloat.Exp10((NFloat)value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] + [InlineData( double.NegativeInfinity, -1.0, 0.0)] + [InlineData(-3.1415926535897932, -0.99927821584092527, CrossPlatformMachineEpsilon64)] // value: -(pi) + [InlineData(-2.7182818284590452, -0.99808698589777568, CrossPlatformMachineEpsilon64)] // value: -(e) + [InlineData(-2.3025850929940457, -0.99501787170355928, CrossPlatformMachineEpsilon64)] // value: -(ln(10)) + [InlineData(-1.5707963267948966, -0.97313395899886387, CrossPlatformMachineEpsilon64)] // value: -(pi / 2) + [InlineData(-1.4426950408889634, -0.96391680717921279, CrossPlatformMachineEpsilon64)] // value: -(log2(e)) + [InlineData(-1.4142135623730950, -0.96147111529967797, CrossPlatformMachineEpsilon64)] // value: -(sqrt(2)) + [InlineData(-1.1283791670955126, -0.92559179413935728, CrossPlatformMachineEpsilon64)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0, -0.9, CrossPlatformMachineEpsilon64)] + [InlineData(-0.78539816339744831, -0.83609136386042335, CrossPlatformMachineEpsilon64)] // value: -(pi / 4) + [InlineData(-0.70710678118654752, -0.80371224006494438, CrossPlatformMachineEpsilon64)] // value: -(1 / sqrt(2)) + [InlineData(-0.69314718055994531, -0.79730043371348270, CrossPlatformMachineEpsilon64)] // value: -(ln(2)) + [InlineData(-0.63661977236758134, -0.76912323548399945, CrossPlatformMachineEpsilon64)] // value: -(2 / pi) + [InlineData(-0.43429448190325183, -0.63212055882855768, CrossPlatformMachineEpsilon64)] // value: -(log10(e)) + [InlineData(-0.31830988618379067, -0.51950362694813132, CrossPlatformMachineEpsilon64)] // value: -(1 / pi) + [InlineData(-0.0, 0.0, 0.0)] + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData( 0.0, 0.0, 0.0)] + [InlineData( 0.31830988618379067, 1.0811811619898573, CrossPlatformMachineEpsilon64 * 10)] // value: (1 / pi) + [InlineData( 0.43429448190325183, 1.7182818284590452, CrossPlatformMachineEpsilon64 * 10)] // value: (log10(e)) + [InlineData( 0.63661977236758134, 3.3313150290214525, CrossPlatformMachineEpsilon64 * 10)] // value: (2 / pi) + [InlineData( 0.69314718055994531, 3.9334096679145963, CrossPlatformMachineEpsilon64 * 10)] // value: (ln(2)) + [InlineData( 0.70710678118654752, 4.0945611704512962, CrossPlatformMachineEpsilon64 * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.78539816339744831, 5.1009598002416937, CrossPlatformMachineEpsilon64 * 10)] // value: (pi / 4) + [InlineData( 1.0, 9.0, CrossPlatformMachineEpsilon64 * 10)] + [InlineData( 1.1283791670955126, 12.439377934644401, CrossPlatformMachineEpsilon64 * 100)] // value: (2 / sqrt(pi)) + [InlineData( 1.4142135623730950, 24.954553519470081, CrossPlatformMachineEpsilon64 * 100)] // value: (sqrt(2)) + [InlineData( 1.4426950408889634, 26.713733786437790, CrossPlatformMachineEpsilon64 * 100)] // value: (log2(e)) + [InlineData( 1.5707963267948966, 36.221710484165167, CrossPlatformMachineEpsilon64 * 100)] // value: (pi / 2) + [InlineData( 2.3025850929940457, 199.71743249053009, CrossPlatformMachineEpsilon64 * 1000)] // value: (ln(10)) + [InlineData( 2.7182818284590452, 521.73529967043665, CrossPlatformMachineEpsilon64 * 1000)] // value: (e) + [InlineData( 3.1415926535897932, 1384.4557313670111, CrossPlatformMachineEpsilon64 * 10000)] // value: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Exp10M1Test64(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, NFloat.Exp10M1((NFloat)value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] + [InlineData( double.NegativeInfinity, double.NaN, 0.0)] + [InlineData(-3.1415926535897932, double.NaN, 0.0)] // value: -(pi) + [InlineData(-2.7182818284590452, double.NaN, 0.0)] // value: -(e) + [InlineData(-1.4142135623730950, double.NaN, 0.0)] // value: -(sqrt(2)) + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData(-1.0, double.NegativeInfinity, 0.0)] + [InlineData(-0.95678608173622775, -3.1415926535897932, CrossPlatformMachineEpsilon64 * 10)] // expected: -(pi) + [InlineData(-0.93401196415468746, -2.7182818284590452, CrossPlatformMachineEpsilon64 * 10)] // expected: -(e) + [InlineData(-0.9, -2.3025850929940457, CrossPlatformMachineEpsilon64 * 10)] // expected: -(ln(10)) + [InlineData(-0.79212042364923809, -1.5707963267948966, CrossPlatformMachineEpsilon64 * 10)] // expected: -(pi / 2) + [InlineData(-0.76370991165547730, -1.4426950408889634, CrossPlatformMachineEpsilon64 * 10)] // expected: -(log2(e)) + [InlineData(-0.75688326556578579, -1.4142135623730950, CrossPlatformMachineEpsilon64 * 10)] // expected: -(sqrt(2)) + [InlineData(-0.67644273609692890, -1.1283791670955126, CrossPlatformMachineEpsilon64 * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(-0.63212055882855768, -1.0, CrossPlatformMachineEpsilon64 * 10)] + [InlineData(-0.54406187223400376, -0.78539816339744831, CrossPlatformMachineEpsilon64)] // expected: -(pi / 4) + [InlineData(-0.50693130860476021, -0.70710678118654752, CrossPlatformMachineEpsilon64)] // expected: -(1 / sqrt(2)) + [InlineData(-0.5, -0.69314718055994531, CrossPlatformMachineEpsilon64)] // expected: -(ln(2)) + [InlineData(-0.47092219173226465, -0.63661977236758134, CrossPlatformMachineEpsilon64)] // expected: -(2 / pi) + [InlineData(-0.0, 0.0, 0.0)] + [InlineData( 0.0, 0.0, 0.0)] + [InlineData( 0.37480222743935863, 0.31830988618379067, CrossPlatformMachineEpsilon64)] // expected: (1 / pi) + [InlineData( 0.54387344397118114, 0.43429448190325183, CrossPlatformMachineEpsilon64)] // expected: (log10(e)) + [InlineData( 0.89008116457222198, 0.63661977236758134, CrossPlatformMachineEpsilon64)] // expected: (2 / pi) + [InlineData( 1.0, 0.69314718055994531, CrossPlatformMachineEpsilon64)] // expected: (ln(2)) + [InlineData( 1.0281149816474725, 0.70710678118654752, CrossPlatformMachineEpsilon64)] // expected: (1 / sqrt(2)) + [InlineData( 1.1932800507380155, 0.78539816339744831, CrossPlatformMachineEpsilon64)] // expected: (pi / 4) + [InlineData( 1.7182818284590452, 1.0, CrossPlatformMachineEpsilon64 * 10)] // value: (e) + [InlineData( 2.0906430223107976, 1.1283791670955126, CrossPlatformMachineEpsilon64 * 10)] // expected: (2 / sqrt(pi)) + [InlineData( 3.1132503787829275, 1.4142135623730950, CrossPlatformMachineEpsilon64 * 10)] // expected: (sqrt(2)) + [InlineData( 3.2320861065570819, 1.4426950408889634, CrossPlatformMachineEpsilon64 * 10)] // expected: (log2(e)) + [InlineData( 3.8104773809653517, 1.5707963267948966, CrossPlatformMachineEpsilon64 * 10)] // expected: (pi / 2) + [InlineData( 9.0, 2.3025850929940457, CrossPlatformMachineEpsilon64 * 10)] // expected: (ln(10)) + [InlineData( 14.154262241479264, 2.7182818284590452, CrossPlatformMachineEpsilon64 * 10)] // expected: (e) + [InlineData( 22.140692632779269, 3.1415926535897932, CrossPlatformMachineEpsilon64 * 10)] // expected: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void LogP1Test64(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, NFloat.LogP1((NFloat)value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] + [InlineData( double.NegativeInfinity, double.NaN, 0.0)] + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData(-1.0, double.NegativeInfinity, 0.0)] + [InlineData(-0.88668526770323913, -3.1415926535897932, CrossPlatformMachineEpsilon64 * 10)] // expected: -(pi) + [InlineData(-0.84804477674208703, -2.7182818284590452, CrossPlatformMachineEpsilon64 * 10)] // expected: -(e) + [InlineData(-0.79730043371348270, -2.3025850929940457, CrossPlatformMachineEpsilon64 * 10)] // expected: -(ln(10)) + [InlineData(-0.66337746317758094, -1.5707963267948966, CrossPlatformMachineEpsilon64 * 10)] // expected: -(pi / 2) + [InlineData(-0.63212055882855768, -1.4426950408889634, CrossPlatformMachineEpsilon64 * 10)] // expected: -(log2(e)) + [InlineData(-0.62478577275351823, -1.4142135623730950, CrossPlatformMachineEpsilon64 * 10)] // expected: -(sqrt(2)) + [InlineData(-0.54257065267770305, -1.1283791670955126, CrossPlatformMachineEpsilon64 * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(-0.5, -1.0, CrossPlatformMachineEpsilon64 * 10)] + [InlineData(-0.41980818962827556, -0.78539816339744831, CrossPlatformMachineEpsilon64)] // expected: -(pi / 4) + [InlineData(-0.38745267346393408, -0.70710678118654752, CrossPlatformMachineEpsilon64)] // expected: -(1 / sqrt(2)) + [InlineData(-0.38149686219842402, -0.69314718055994531, CrossPlatformMachineEpsilon64)] // expected: -(ln(2)) + [InlineData(-0.35678175806699512, -0.63661977236758134, CrossPlatformMachineEpsilon64)] // expected: -(2 / pi) + [InlineData(-0.25994442604454821, -0.43429448190325183, CrossPlatformMachineEpsilon64)] // expected: -(log10(e)) + [InlineData(-0.19799112103854805, -0.31830988618379067, CrossPlatformMachineEpsilon64)] // expected: -(1 / pi) + [InlineData(-0.0, 0.0, 0.0)] + [InlineData( 0.0, 0.0, 0.0)] + [InlineData( 0.24686898890063831, 0.31830988618379067, CrossPlatformMachineEpsilon64)] // expected: (1 / pi) + [InlineData( 0.35124987256726717, 0.43429448190325183, CrossPlatformMachineEpsilon64)] // expected: (log10(e)) + [InlineData( 0.55468227548210009, 0.63661977236758134, CrossPlatformMachineEpsilon64)] // expected: (2 / pi) + [InlineData( 0.61680667224167466, 0.69314718055994531, CrossPlatformMachineEpsilon64)] // expected: (ln(2)) + [InlineData( 0.63252691943815284, 0.70710678118654752, CrossPlatformMachineEpsilon64)] // expected: (1 / sqrt(2)) + [InlineData( 0.72356793412734949, 0.78539816339744831, CrossPlatformMachineEpsilon64)] // expected: (pi / 4) + [InlineData( 1.0, 1.0, CrossPlatformMachineEpsilon64 * 10)] // value: (e) + [InlineData( 1.1861299583286618, 1.1283791670955126, CrossPlatformMachineEpsilon64 * 10)] // expected: (2 / sqrt(pi)) + [InlineData( 1.6651441426902252, 1.4142135623730950, CrossPlatformMachineEpsilon64 * 10)] // expected: (sqrt(2)) + [InlineData( 1.7182818284590452, 1.4426950408889634, CrossPlatformMachineEpsilon64 * 10)] // expected: (log2(e)) + [InlineData( 1.9706864235520193, 1.5707963267948966, CrossPlatformMachineEpsilon64 * 10)] // expected: (pi / 2) + [InlineData( 3.9334096679145963, 2.3025850929940457, CrossPlatformMachineEpsilon64 * 10)] // expected: (ln(10)) + [InlineData( 5.5808859910179210, 2.7182818284590452, CrossPlatformMachineEpsilon64 * 10)] // expected: (e) + [InlineData( 7.8249778270762876, 3.1415926535897932, CrossPlatformMachineEpsilon64 * 10)] // expected: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Log2P1Test64(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, NFloat.Log2P1((NFloat)value), allowedVariance); + } + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.Is64BitProcess))] + [InlineData( double.NegativeInfinity, double.NaN, 0.0)] + [InlineData(-3.1415926535897932, double.NaN, 0.0)] // value: -(pi) + [InlineData(-2.7182818284590452, double.NaN, 0.0)] // value: -(e) + [InlineData(-1.4142135623730950, double.NaN, 0.0)] // value: -(sqrt(2)) + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData(-1.0, double.NegativeInfinity, 0.0)] + [InlineData(-0.99808698589777568, -2.7182818284590452, CrossPlatformMachineEpsilon64 * 10)] // expected: -(e) + [InlineData(-0.99501787170355928, -2.3025850929940457, CrossPlatformMachineEpsilon64 * 10)] // expected: -(ln(10)) + [InlineData(-0.97313395899886387, -1.5707963267948966, CrossPlatformMachineEpsilon64 * 10)] // expected: -(pi / 2) + [InlineData(-0.96391680717921279, -1.4426950408889634, CrossPlatformMachineEpsilon64 * 10)] // expected: -(log2(e)) + [InlineData(-0.96147111529967797, -1.4142135623730950, CrossPlatformMachineEpsilon64 * 10)] // expected: -(sqrt(2)) + [InlineData(-0.92559179413935728, -1.1283791670955126, CrossPlatformMachineEpsilon64 * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(-0.9, -1.0, CrossPlatformMachineEpsilon64 * 10)] + [InlineData(-0.83609136386042335, -0.78539816339744831, CrossPlatformMachineEpsilon64)] // expected: -(pi / 4) + [InlineData(-0.80371224006494438, -0.70710678118654752, CrossPlatformMachineEpsilon64)] // expected: -(1 / sqrt(2)) + [InlineData(-0.79730043371348270, -0.69314718055994531, CrossPlatformMachineEpsilon64)] // expected: -(ln(2)) + [InlineData(-0.76912323548399945, -0.63661977236758134, CrossPlatformMachineEpsilon64)] // expected: -(2 / pi) + [InlineData(-0.63212055882855768, -0.43429448190325183, CrossPlatformMachineEpsilon64)] // expected: -(log10(e)) + [InlineData(-0.51950362694813132, -0.31830988618379067, CrossPlatformMachineEpsilon64)] // expected: -(1 / pi) + [InlineData(-0.0, 0.0, 0.0)] + [InlineData( 0.0, 0.0, 0.0)] + [InlineData( 1.0811811619898573, 0.31830988618379067, CrossPlatformMachineEpsilon64)] // expected: (1 / pi) + [InlineData( 1.7182818284590452, 0.43429448190325183, CrossPlatformMachineEpsilon64)] // expected: (log10(e)) value: (e) + [InlineData( 3.3313150290214525, 0.63661977236758134, CrossPlatformMachineEpsilon64)] // expected: (2 / pi) + [InlineData( 3.9334096679145963, 0.69314718055994531, CrossPlatformMachineEpsilon64)] // expected: (ln(2)) + [InlineData( 4.0945611704512962, 0.70710678118654752, CrossPlatformMachineEpsilon64)] // expected: (1 / sqrt(2)) + [InlineData( 5.1009598002416937, 0.78539816339744831, CrossPlatformMachineEpsilon64)] // expected: (pi / 4) + [InlineData( 9.0, 1.0, CrossPlatformMachineEpsilon64 * 10)] + [InlineData( 12.439377934644401, 1.1283791670955126, CrossPlatformMachineEpsilon64 * 10)] // expected: (2 / sqrt(pi)) + [InlineData( 24.954553519470081, 1.4142135623730950, CrossPlatformMachineEpsilon64 * 10)] // expected: (sqrt(2)) + [InlineData( 26.713733786437790, 1.4426950408889634, CrossPlatformMachineEpsilon64 * 10)] // expected: (log2(e)) + [InlineData( 36.221710484165167, 1.5707963267948966, CrossPlatformMachineEpsilon64 * 10)] // expected: (pi / 2) + [InlineData( 199.71743249053009, 2.3025850929940457, CrossPlatformMachineEpsilon64 * 10)] // expected: (ln(10)) + [InlineData( 521.73529967043665, 2.7182818284590452, CrossPlatformMachineEpsilon64 * 10)] // expected: (e) + [InlineData( 1384.4557313670111, 3.1415926535897932, CrossPlatformMachineEpsilon64 * 10)] // expected: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Log10P1Test64(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, NFloat.Log10P1((NFloat)value), allowedVariance); + } } } diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs index d87255a7ee53df..48e4fda16c47ee 100644 --- a/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -2082,6 +2082,11 @@ public DivideByZeroException(string? message, System.Exception? innerException) 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; } + public static double Exp10(double x) { throw null; } + public static double Exp10M1(double x) { throw null; } + public static double Exp2(double x) { throw null; } + public static double Exp2M1(double x) { throw null; } + public static double ExpM1(double x) { throw null; } public static double Floor(double x) { throw null; } public static double FusedMultiplyAdd(double left, double right, double addend) { throw null; } public override int GetHashCode() { throw null; } @@ -2100,7 +2105,10 @@ public DivideByZeroException(string? message, System.Exception? innerException) public static double Log(double x) { throw null; } public static double Log(double x, double newBase) { throw null; } public static double Log10(double x) { throw null; } + public static double Log10P1(double x) { throw null; } public static double Log2(double value) { throw null; } + public static double Log2P1(double x) { throw null; } + public static double LogP1(double x) { throw null; } public static double Max(double x, double y) { throw null; } public static double MaxMagnitude(double x, double y) { throw null; } public static double MaxMagnitudeNumber(double x, double y) { throw null; } @@ -2671,6 +2679,11 @@ public GopherStyleUriParser() { } 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; } + public static System.Half Exp10(System.Half x) { throw null; } + public static System.Half Exp10M1(System.Half x) { throw null; } + public static System.Half Exp2(System.Half x) { throw null; } + public static System.Half Exp2M1(System.Half x) { throw null; } + public static System.Half ExpM1(System.Half x) { throw null; } 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; } @@ -2688,7 +2701,10 @@ public GopherStyleUriParser() { } public static System.Half Log(System.Half x) { throw null; } public static System.Half Log(System.Half x, System.Half newBase) { throw null; } public static System.Half Log10(System.Half x) { throw null; } + public static System.Half Log10P1(System.Half x) { throw null; } public static System.Half Log2(System.Half value) { throw null; } + public static System.Half Log2P1(System.Half x) { throw null; } + public static System.Half LogP1(System.Half x) { throw null; } public static System.Half Max(System.Half x, System.Half y) { throw null; } public static System.Half MaxMagnitude(System.Half x, System.Half y) { throw null; } public static System.Half MaxMagnitudeNumber(System.Half x, System.Half y) { throw null; } @@ -4276,6 +4292,11 @@ public SerializableAttribute() { } 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; } + public static float Exp10(float x) { throw null; } + public static float Exp10M1(float x) { throw null; } + public static float Exp2(float x) { throw null; } + public static float Exp2M1(float x) { throw null; } + public static float ExpM1(float x) { throw null; } public static float Floor(float x) { throw null; } public static float FusedMultiplyAdd(float left, float right, float addend) { throw null; } public override int GetHashCode() { throw null; } @@ -4294,7 +4315,10 @@ public SerializableAttribute() { } public static float Log(float x) { throw null; } public static float Log(float x, float newBase) { throw null; } public static float Log10(float x) { throw null; } + public static float Log10P1(float x) { throw null; } public static float Log2(float value) { throw null; } + public static float Log2P1(float x) { throw null; } + public static float LogP1(float x) { throw null; } public static float Max(float x, float y) { throw null; } public static float MaxMagnitude(float x, float y) { throw null; } public static float MaxMagnitudeNumber(float x, float y) { throw null; } @@ -9622,6 +9646,11 @@ public partial interface IEqualityOperators : System.IEquatable where TSelf : System.Numerics.IExponentialFunctions { static abstract TSelf Exp(TSelf x); + static abstract TSelf Exp10(TSelf x); + static abstract TSelf Exp10M1(TSelf x); + static abstract TSelf Exp2(TSelf x); + static abstract TSelf Exp2M1(TSelf x); + static abstract TSelf ExpM1(TSelf x); } public partial interface IFloatingPointIeee754 : System.IComparable, System.IComparable, System.IEquatable, System.IFormattable, System.IParsable, System.ISpanFormattable, System.ISpanParsable, System.Numerics.IAdditionOperators, System.Numerics.IAdditiveIdentity, System.Numerics.IComparisonOperators, System.Numerics.IDecrementOperators, System.Numerics.IDivisionOperators, System.Numerics.IEqualityOperators, System.Numerics.IExponentialFunctions, System.Numerics.IFloatingPoint, System.Numerics.IHyperbolicFunctions, System.Numerics.IIncrementOperators, System.Numerics.ILogarithmicFunctions, System.Numerics.IModulusOperators, System.Numerics.IMultiplicativeIdentity, System.Numerics.IMultiplyOperators, System.Numerics.INumber, System.Numerics.INumberBase, System.Numerics.IPowerFunctions, System.Numerics.IRootFunctions, System.Numerics.ISignedNumber, System.Numerics.ISubtractionOperators, System.Numerics.ITrigonometricFunctions, System.Numerics.IUnaryNegationOperators, System.Numerics.IUnaryPlusOperators where TSelf : System.Numerics.IFloatingPointIeee754 { @@ -9694,7 +9723,10 @@ public partial interface ILogarithmicFunctions where TSelf : System.Numer static abstract TSelf Log(TSelf x); static abstract TSelf Log(TSelf x, TSelf newBase); static abstract TSelf Log10(TSelf x); + static abstract TSelf Log10P1(TSelf x); static abstract TSelf Log2(TSelf x); + static abstract TSelf Log2P1(TSelf x); + static abstract TSelf LogP1(TSelf x); } public partial interface IMinMaxValue where TSelf : System.Numerics.IMinMaxValue { diff --git a/src/libraries/System.Runtime/tests/System/DoubleTests.cs b/src/libraries/System.Runtime/tests/System/DoubleTests.cs index a92376993c2a6e..ad3b09645ad380 100644 --- a/src/libraries/System.Runtime/tests/System/DoubleTests.cs +++ b/src/libraries/System.Runtime/tests/System/DoubleTests.cs @@ -15,6 +15,20 @@ public class DoubleTests { // NOTE: Consider duplicating any tests added here in SingleTests.cs + // binary64 (double) has a machine epsilon of 2^-52 (approx. 2.22e-16). However, this + // is slightly too accurate when writing tests meant to run against libm implementations + // for various platforms. 2^-50 (approx. 8.88e-16) seems to be as accurate as we can get. + // + // The tests themselves will take CrossPlatformMachineEpsilon and adjust it according to the expected result + // so that the delta used for comparison will compare the most significant digits and ignore + // any digits that are outside the double precision range (15-17 digits). + // + // For example, a test with an expect result in the format of 0.xxxxxxxxxxxxxxxxx will use + // CrossPlatformMachineEpsilon for the variance, while an expected result in the format of 0.0xxxxxxxxxxxxxxxxx + // will use CrossPlatformMachineEpsilon / 10 and expected result in the format of x.xxxxxxxxxxxxxxxx will + // use CrossPlatformMachineEpsilon * 10. + internal const double CrossPlatformMachineEpsilon = 8.8817841970012523e-16; + [Theory] [InlineData("a")] [InlineData(234.0f)] @@ -907,5 +921,323 @@ public static void MinNumberTest(double x, double y, double expectedResult) { AssertExtensions.Equal(expectedResult, double.MinNumber(x, y), 0.0); } + + [Theory] + [InlineData( double.NegativeInfinity, -1.0, CrossPlatformMachineEpsilon * 10)] + [InlineData(-3.1415926535897932, -0.95678608173622775, CrossPlatformMachineEpsilon)] // value: -(pi) + [InlineData(-2.7182818284590452, -0.93401196415468746, CrossPlatformMachineEpsilon)] // value: -(e) + [InlineData(-2.3025850929940457, -0.9, CrossPlatformMachineEpsilon)] // value: -(ln(10)) + [InlineData(-1.5707963267948966, -0.79212042364923809, CrossPlatformMachineEpsilon)] // value: -(pi / 2) + [InlineData(-1.4426950408889634, -0.76370991165547730, CrossPlatformMachineEpsilon)] // value: -(log2(e)) + [InlineData(-1.4142135623730950, -0.75688326556578579, CrossPlatformMachineEpsilon)] // value: -(sqrt(2)) + [InlineData(-1.1283791670955126, -0.67644273609692890, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0, -0.63212055882855768, CrossPlatformMachineEpsilon)] + [InlineData(-0.78539816339744831, -0.54406187223400376, CrossPlatformMachineEpsilon)] // value: -(pi / 4) + [InlineData(-0.70710678118654752, -0.50693130860476021, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.69314718055994531, -0.5, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.63661977236758134, -0.47092219173226465, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.43429448190325183, -0.35227851485819935, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.31830988618379067, -0.27262265070478353, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0, 0.0, 0.0)] + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData( 0.0, 0.0, 0.0)] + [InlineData( 0.31830988618379067, 0.37480222743935863, CrossPlatformMachineEpsilon)] // value: (1 / pi) + [InlineData( 0.43429448190325183, 0.54387344397118114, CrossPlatformMachineEpsilon)] // value: (log10(e)) + [InlineData( 0.63661977236758134, 0.89008116457222198, CrossPlatformMachineEpsilon)] // value: (2 / pi) + [InlineData( 0.69314718055994531, 1.0, CrossPlatformMachineEpsilon * 10)] // value: (ln(2)) + [InlineData( 0.70710678118654752, 1.0281149816474725, CrossPlatformMachineEpsilon * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.78539816339744831, 1.1932800507380155, CrossPlatformMachineEpsilon * 10)] // value: (pi / 4) + [InlineData( 1.0, 1.7182818284590452, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.1283791670955126, 2.0906430223107976, CrossPlatformMachineEpsilon * 10)] // value: (2 / sqrt(pi)) + [InlineData( 1.4142135623730950, 3.1132503787829275, CrossPlatformMachineEpsilon * 10)] // value: (sqrt(2)) + [InlineData( 1.4426950408889634, 3.2320861065570819, CrossPlatformMachineEpsilon * 10)] // value: (log2(e)) + [InlineData( 1.5707963267948966, 3.8104773809653517, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2) + [InlineData( 2.3025850929940457, 9.0, CrossPlatformMachineEpsilon * 10)] // value: (ln(10)) + [InlineData( 2.7182818284590452, 14.154262241479264, CrossPlatformMachineEpsilon * 100)] // value: (e) + [InlineData( 3.1415926535897932, 22.140692632779269, CrossPlatformMachineEpsilon * 100)] // value: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void ExpM1Test(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, double.ExpM1(value), allowedVariance); + } + + [Theory] + [InlineData( double.NegativeInfinity, 0.0, 0.0)] + [InlineData(-3.1415926535897932, 0.11331473229676087, CrossPlatformMachineEpsilon)] // value: -(pi) + [InlineData(-2.7182818284590452, 0.15195522325791297, CrossPlatformMachineEpsilon)] // value: -(e) + [InlineData(-2.3025850929940457, 0.20269956628651730, CrossPlatformMachineEpsilon)] // value: -(ln(10)) + [InlineData(-1.5707963267948966, 0.33662253682241906, CrossPlatformMachineEpsilon)] // value: -(pi / 2) + [InlineData(-1.4426950408889634, 0.36787944117144232, CrossPlatformMachineEpsilon)] // value: -(log2(e)) + [InlineData(-1.4142135623730950, 0.37521422724648177, CrossPlatformMachineEpsilon)] // value: -(sqrt(2)) + [InlineData(-1.1283791670955126, 0.45742934732229695, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0, 0.5, CrossPlatformMachineEpsilon)] + [InlineData(-0.78539816339744831, 0.58019181037172444, CrossPlatformMachineEpsilon)] // value: -(pi / 4) + [InlineData(-0.70710678118654752, 0.61254732653606592, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.69314718055994531, 0.61850313780157598, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.63661977236758134, 0.64321824193300488, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.43429448190325183, 0.74005557395545179, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.31830988618379067, 0.80200887896145195, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0, 1.0, 0.0)] + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData( 0.0, 1.0, 0.0)] + [InlineData( 0.31830988618379067, 1.2468689889006383, CrossPlatformMachineEpsilon * 10)] // value: (1 / pi) + [InlineData( 0.43429448190325183, 1.3512498725672672, CrossPlatformMachineEpsilon * 10)] // value: (log10(e)) + [InlineData( 0.63661977236758134, 1.5546822754821001, CrossPlatformMachineEpsilon * 10)] // value: (2 / pi) + [InlineData( 0.69314718055994531, 1.6168066722416747, CrossPlatformMachineEpsilon * 10)] // value: (ln(2)) + [InlineData( 0.70710678118654752, 1.6325269194381528, CrossPlatformMachineEpsilon * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.78539816339744831, 1.7235679341273495, CrossPlatformMachineEpsilon * 10)] // value: (pi / 4) + [InlineData( 1.0, 2.0, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.1283791670955126, 2.1861299583286618, CrossPlatformMachineEpsilon * 10)] // value: (2 / sqrt(pi)) + [InlineData( 1.4142135623730950, 2.6651441426902252, CrossPlatformMachineEpsilon * 10)] // value: (sqrt(2)) + [InlineData( 1.4426950408889634, 2.7182818284590452, CrossPlatformMachineEpsilon * 10)] // value: (log2(e)) + [InlineData( 1.5707963267948966, 2.9706864235520193, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2) + [InlineData( 2.3025850929940457, 4.9334096679145963, CrossPlatformMachineEpsilon * 10)] // value: (ln(10)) + [InlineData( 2.7182818284590452, 6.5808859910179210, CrossPlatformMachineEpsilon * 10)] // value: (e) + [InlineData( 3.1415926535897932, 8.8249778270762876, CrossPlatformMachineEpsilon * 10)] // value: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Exp2Test(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, double.Exp2(value), allowedVariance); + } + + [Theory] + [InlineData( double.NegativeInfinity, -1.0, 0.0)] + [InlineData(-3.1415926535897932, -0.88668526770323913, CrossPlatformMachineEpsilon)] // value: -(pi) + [InlineData(-2.7182818284590452, -0.84804477674208703, CrossPlatformMachineEpsilon)] // value: -(e) + [InlineData(-2.3025850929940457, -0.79730043371348270, CrossPlatformMachineEpsilon)] // value: -(ln(10)) + [InlineData(-1.5707963267948966, -0.66337746317758094, CrossPlatformMachineEpsilon)] // value: -(pi / 2) + [InlineData(-1.4426950408889634, -0.63212055882855768, CrossPlatformMachineEpsilon)] // value: -(log2(e)) + [InlineData(-1.4142135623730950, -0.62478577275351823, CrossPlatformMachineEpsilon)] // value: -(sqrt(2)) + [InlineData(-1.1283791670955126, -0.54257065267770305, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0, -0.5, CrossPlatformMachineEpsilon)] + [InlineData(-0.78539816339744831, -0.41980818962827556, CrossPlatformMachineEpsilon)] // value: -(pi / 4) + [InlineData(-0.70710678118654752, -0.38745267346393408, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.69314718055994531, -0.38149686219842402, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.63661977236758134, -0.35678175806699512, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.43429448190325183, -0.25994442604454821, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.31830988618379067, -0.19799112103854805, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0, 0.0, 0.0)] + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData( 0.0, 0.0, 0.0)] + [InlineData( 0.31830988618379067, 0.24686898890063831, CrossPlatformMachineEpsilon)] // value: (1 / pi) + [InlineData( 0.43429448190325183, 0.35124987256726717, CrossPlatformMachineEpsilon)] // value: (log10(e)) + [InlineData( 0.63661977236758134, 0.55468227548210009, CrossPlatformMachineEpsilon)] // value: (2 / pi) + [InlineData( 0.69314718055994531, 0.61680667224167466, CrossPlatformMachineEpsilon)] // value: (ln(2)) + [InlineData( 0.70710678118654752, 0.63252691943815284, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2)) + [InlineData( 0.78539816339744831, 0.72356793412734949, CrossPlatformMachineEpsilon)] // value: (pi / 4) + [InlineData( 1.0, 1.0, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.1283791670955126, 1.1861299583286618, CrossPlatformMachineEpsilon * 10)] // value: (2 / sqrt(pi)) + [InlineData( 1.4142135623730950, 1.6651441426902252, CrossPlatformMachineEpsilon * 10)] // value: (sqrt(2)) + [InlineData( 1.4426950408889634, 1.7182818284590452, CrossPlatformMachineEpsilon * 10)] // value: (log2(e)) + [InlineData( 1.5707963267948966, 1.9706864235520193, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2) + [InlineData( 2.3025850929940457, 3.9334096679145963, CrossPlatformMachineEpsilon * 10)] // value: (ln(10)) + [InlineData( 2.7182818284590452, 5.5808859910179210, CrossPlatformMachineEpsilon * 10)] // value: (e) + [InlineData( 3.1415926535897932, 7.8249778270762876, CrossPlatformMachineEpsilon * 10)] // value: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Exp2M1Test(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, double.Exp2M1(value), allowedVariance); + } + + [Theory] + [InlineData( double.NegativeInfinity, 0.0, 0.0)] + [InlineData(-3.1415926535897932, 0.00072178415907472774, CrossPlatformMachineEpsilon / 1000)] // value: -(pi) + [InlineData(-2.7182818284590452, 0.0019130141022243176, CrossPlatformMachineEpsilon / 100)] // value: -(e) + [InlineData(-2.3025850929940457, 0.0049821282964407206, CrossPlatformMachineEpsilon / 100)] // value: -(ln(10)) + [InlineData(-1.5707963267948966, 0.026866041001136132, CrossPlatformMachineEpsilon / 10)] // value: -(pi / 2) + [InlineData(-1.4426950408889634, 0.036083192820787210, CrossPlatformMachineEpsilon / 10)] // value: -(log2(e)) + [InlineData(-1.4142135623730950, 0.038528884700322026, CrossPlatformMachineEpsilon / 10)] // value: -(sqrt(2)) + [InlineData(-1.1283791670955126, 0.074408205860642723, CrossPlatformMachineEpsilon / 10)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0, 0.1, CrossPlatformMachineEpsilon)] + [InlineData(-0.78539816339744831, 0.16390863613957665, CrossPlatformMachineEpsilon)] // value: -(pi / 4) + [InlineData(-0.70710678118654752, 0.19628775993505562, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.69314718055994531, 0.20269956628651730, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.63661977236758134, 0.23087676451600055, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.43429448190325183, 0.36787944117144232, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.31830988618379067, 0.48049637305186868, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0, 1.0, 0.0)] + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData( 0.0, 1.0, 0.0)] + [InlineData( 0.31830988618379067, 2.0811811619898573, CrossPlatformMachineEpsilon * 10)] // value: (1 / pi) + [InlineData( 0.43429448190325183, 2.7182818284590452, CrossPlatformMachineEpsilon * 10)] // value: (log10(e)) + [InlineData( 0.63661977236758134, 4.3313150290214525, CrossPlatformMachineEpsilon * 10)] // value: (2 / pi) + [InlineData( 0.69314718055994531, 4.9334096679145963, CrossPlatformMachineEpsilon * 10)] // value: (ln(2)) + [InlineData( 0.70710678118654752, 5.0945611704512962, CrossPlatformMachineEpsilon * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.78539816339744831, 6.1009598002416937, CrossPlatformMachineEpsilon * 10)] // value: (pi / 4) + [InlineData( 1.0, 10.0, CrossPlatformMachineEpsilon * 100)] + [InlineData( 1.1283791670955126, 13.439377934644401, CrossPlatformMachineEpsilon * 100)] // value: (2 / sqrt(pi)) + [InlineData( 1.4142135623730950, 25.954553519470081, CrossPlatformMachineEpsilon * 100)] // value: (sqrt(2)) + [InlineData( 1.4426950408889634, 27.713733786437790, CrossPlatformMachineEpsilon * 100)] // value: (log2(e)) + [InlineData( 1.5707963267948966, 37.221710484165167, CrossPlatformMachineEpsilon * 100)] // value: (pi / 2) + [InlineData( 2.3025850929940457, 200.71743249053009, CrossPlatformMachineEpsilon * 1000)] // value: (ln(10)) + [InlineData( 2.7182818284590452, 522.73529967043665, CrossPlatformMachineEpsilon * 1000)] // value: (e) + [InlineData( 3.1415926535897932, 1385.4557313670111, CrossPlatformMachineEpsilon * 10000)] // value: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Exp10Test(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, double.Exp10(value), allowedVariance); + } + + [Theory] + [InlineData( double.NegativeInfinity, -1.0, 0.0)] + [InlineData(-3.1415926535897932, -0.99927821584092527, CrossPlatformMachineEpsilon)] // value: -(pi) + [InlineData(-2.7182818284590452, -0.99808698589777568, CrossPlatformMachineEpsilon)] // value: -(e) + [InlineData(-2.3025850929940457, -0.99501787170355928, CrossPlatformMachineEpsilon)] // value: -(ln(10)) + [InlineData(-1.5707963267948966, -0.97313395899886387, CrossPlatformMachineEpsilon)] // value: -(pi / 2) + [InlineData(-1.4426950408889634, -0.96391680717921279, CrossPlatformMachineEpsilon)] // value: -(log2(e)) + [InlineData(-1.4142135623730950, -0.96147111529967797, CrossPlatformMachineEpsilon)] // value: -(sqrt(2)) + [InlineData(-1.1283791670955126, -0.92559179413935728, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0, -0.9, CrossPlatformMachineEpsilon)] + [InlineData(-0.78539816339744831, -0.83609136386042335, CrossPlatformMachineEpsilon)] // value: -(pi / 4) + [InlineData(-0.70710678118654752, -0.80371224006494438, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.69314718055994531, -0.79730043371348270, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.63661977236758134, -0.76912323548399945, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.43429448190325183, -0.63212055882855768, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.31830988618379067, -0.51950362694813132, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0, 0.0, 0.0)] + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData( 0.0, 0.0, 0.0)] + [InlineData( 0.31830988618379067, 1.0811811619898573, CrossPlatformMachineEpsilon * 10)] // value: (1 / pi) + [InlineData( 0.43429448190325183, 1.7182818284590452, CrossPlatformMachineEpsilon * 10)] // value: (log10(e)) + [InlineData( 0.63661977236758134, 3.3313150290214525, CrossPlatformMachineEpsilon * 10)] // value: (2 / pi) + [InlineData( 0.69314718055994531, 3.9334096679145963, CrossPlatformMachineEpsilon * 10)] // value: (ln(2)) + [InlineData( 0.70710678118654752, 4.0945611704512962, CrossPlatformMachineEpsilon * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.78539816339744831, 5.1009598002416937, CrossPlatformMachineEpsilon * 10)] // value: (pi / 4) + [InlineData( 1.0, 9.0, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.1283791670955126, 12.439377934644401, CrossPlatformMachineEpsilon * 100)] // value: (2 / sqrt(pi)) + [InlineData( 1.4142135623730950, 24.954553519470081, CrossPlatformMachineEpsilon * 100)] // value: (sqrt(2)) + [InlineData( 1.4426950408889634, 26.713733786437790, CrossPlatformMachineEpsilon * 100)] // value: (log2(e)) + [InlineData( 1.5707963267948966, 36.221710484165167, CrossPlatformMachineEpsilon * 100)] // value: (pi / 2) + [InlineData( 2.3025850929940457, 199.71743249053009, CrossPlatformMachineEpsilon * 1000)] // value: (ln(10)) + [InlineData( 2.7182818284590452, 521.73529967043665, CrossPlatformMachineEpsilon * 1000)] // value: (e) + [InlineData( 3.1415926535897932, 1384.4557313670111, CrossPlatformMachineEpsilon * 10000)] // value: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Exp10M1Test(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, double.Exp10M1(value), allowedVariance); + } + + [Theory] + [InlineData( double.NegativeInfinity, double.NaN, 0.0)] + [InlineData(-3.1415926535897932, double.NaN, 0.0)] // value: -(pi) + [InlineData(-2.7182818284590452, double.NaN, 0.0)] // value: -(e) + [InlineData(-1.4142135623730950, double.NaN, 0.0)] // value: -(sqrt(2)) + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData(-1.0, double.NegativeInfinity, 0.0)] + [InlineData(-0.95678608173622775, -3.1415926535897932, CrossPlatformMachineEpsilon * 10)] // expected: -(pi) + [InlineData(-0.93401196415468746, -2.7182818284590452, CrossPlatformMachineEpsilon * 10)] // expected: -(e) + [InlineData(-0.9, -2.3025850929940457, CrossPlatformMachineEpsilon * 10)] // expected: -(ln(10)) + [InlineData(-0.79212042364923809, -1.5707963267948966, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(-0.76370991165547730, -1.4426950408889634, CrossPlatformMachineEpsilon * 10)] // expected: -(log2(e)) + [InlineData(-0.75688326556578579, -1.4142135623730950, CrossPlatformMachineEpsilon * 10)] // expected: -(sqrt(2)) + [InlineData(-0.67644273609692890, -1.1283791670955126, CrossPlatformMachineEpsilon * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(-0.63212055882855768, -1.0, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.54406187223400376, -0.78539816339744831, CrossPlatformMachineEpsilon)] // expected: -(pi / 4) + [InlineData(-0.50693130860476021, -0.70710678118654752, CrossPlatformMachineEpsilon)] // expected: -(1 / sqrt(2)) + [InlineData(-0.5, -0.69314718055994531, CrossPlatformMachineEpsilon)] // expected: -(ln(2)) + [InlineData(-0.47092219173226465, -0.63661977236758134, CrossPlatformMachineEpsilon)] // expected: -(2 / pi) + [InlineData(-0.0, 0.0, 0.0)] + [InlineData( 0.0, 0.0, 0.0)] + [InlineData( 0.37480222743935863, 0.31830988618379067, CrossPlatformMachineEpsilon)] // expected: (1 / pi) + [InlineData( 0.54387344397118114, 0.43429448190325183, CrossPlatformMachineEpsilon)] // expected: (log10(e)) + [InlineData( 0.89008116457222198, 0.63661977236758134, CrossPlatformMachineEpsilon)] // expected: (2 / pi) + [InlineData( 1.0, 0.69314718055994531, CrossPlatformMachineEpsilon)] // expected: (ln(2)) + [InlineData( 1.0281149816474725, 0.70710678118654752, CrossPlatformMachineEpsilon)] // expected: (1 / sqrt(2)) + [InlineData( 1.1932800507380155, 0.78539816339744831, CrossPlatformMachineEpsilon)] // expected: (pi / 4) + [InlineData( 1.7182818284590452, 1.0, CrossPlatformMachineEpsilon * 10)] // value: (e) + [InlineData( 2.0906430223107976, 1.1283791670955126, CrossPlatformMachineEpsilon * 10)] // expected: (2 / sqrt(pi)) + [InlineData( 3.1132503787829275, 1.4142135623730950, CrossPlatformMachineEpsilon * 10)] // expected: (sqrt(2)) + [InlineData( 3.2320861065570819, 1.4426950408889634, CrossPlatformMachineEpsilon * 10)] // expected: (log2(e)) + [InlineData( 3.8104773809653517, 1.5707963267948966, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData( 9.0, 2.3025850929940457, CrossPlatformMachineEpsilon * 10)] // expected: (ln(10)) + [InlineData( 14.154262241479264, 2.7182818284590452, CrossPlatformMachineEpsilon * 10)] // expected: (e) + [InlineData( 22.140692632779269, 3.1415926535897932, CrossPlatformMachineEpsilon * 10)] // expected: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void LogP1Test(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, double.LogP1(value), allowedVariance); + } + + [Theory] + [InlineData( double.NegativeInfinity, double.NaN, 0.0)] + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData(-1.0, double.NegativeInfinity, 0.0)] + [InlineData(-0.88668526770323913, -3.1415926535897932, CrossPlatformMachineEpsilon * 10)] // expected: -(pi) + [InlineData(-0.84804477674208703, -2.7182818284590452, CrossPlatformMachineEpsilon * 10)] // expected: -(e) + [InlineData(-0.79730043371348270, -2.3025850929940457, CrossPlatformMachineEpsilon * 10)] // expected: -(ln(10)) + [InlineData(-0.66337746317758094, -1.5707963267948966, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(-0.63212055882855768, -1.4426950408889634, CrossPlatformMachineEpsilon * 10)] // expected: -(log2(e)) + [InlineData(-0.62478577275351823, -1.4142135623730950, CrossPlatformMachineEpsilon * 10)] // expected: -(sqrt(2)) + [InlineData(-0.54257065267770305, -1.1283791670955126, CrossPlatformMachineEpsilon * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(-0.5, -1.0, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.41980818962827556, -0.78539816339744831, CrossPlatformMachineEpsilon)] // expected: -(pi / 4) + [InlineData(-0.38745267346393408, -0.70710678118654752, CrossPlatformMachineEpsilon)] // expected: -(1 / sqrt(2)) + [InlineData(-0.38149686219842402, -0.69314718055994531, CrossPlatformMachineEpsilon)] // expected: -(ln(2)) + [InlineData(-0.35678175806699512, -0.63661977236758134, CrossPlatformMachineEpsilon)] // expected: -(2 / pi) + [InlineData(-0.25994442604454821, -0.43429448190325183, CrossPlatformMachineEpsilon)] // expected: -(log10(e)) + [InlineData(-0.19799112103854805, -0.31830988618379067, CrossPlatformMachineEpsilon)] // expected: -(1 / pi) + [InlineData(-0.0, 0.0, 0.0)] + [InlineData( 0.0, 0.0, 0.0)] + [InlineData( 0.24686898890063831, 0.31830988618379067, CrossPlatformMachineEpsilon)] // expected: (1 / pi) + [InlineData( 0.35124987256726717, 0.43429448190325183, CrossPlatformMachineEpsilon)] // expected: (log10(e)) + [InlineData( 0.55468227548210009, 0.63661977236758134, CrossPlatformMachineEpsilon)] // expected: (2 / pi) + [InlineData( 0.61680667224167466, 0.69314718055994531, CrossPlatformMachineEpsilon)] // expected: (ln(2)) + [InlineData( 0.63252691943815284, 0.70710678118654752, CrossPlatformMachineEpsilon)] // expected: (1 / sqrt(2)) + [InlineData( 0.72356793412734949, 0.78539816339744831, CrossPlatformMachineEpsilon)] // expected: (pi / 4) + [InlineData( 1.0, 1.0, CrossPlatformMachineEpsilon * 10)] // value: (e) + [InlineData( 1.1861299583286618, 1.1283791670955126, CrossPlatformMachineEpsilon * 10)] // expected: (2 / sqrt(pi)) + [InlineData( 1.6651441426902252, 1.4142135623730950, CrossPlatformMachineEpsilon * 10)] // expected: (sqrt(2)) + [InlineData( 1.7182818284590452, 1.4426950408889634, CrossPlatformMachineEpsilon * 10)] // expected: (log2(e)) + [InlineData( 1.9706864235520193, 1.5707963267948966, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData( 3.9334096679145963, 2.3025850929940457, CrossPlatformMachineEpsilon * 10)] // expected: (ln(10)) + [InlineData( 5.5808859910179210, 2.7182818284590452, CrossPlatformMachineEpsilon * 10)] // expected: (e) + [InlineData( 7.8249778270762876, 3.1415926535897932, CrossPlatformMachineEpsilon * 10)] // expected: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Log2P1Test(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, double.Log2P1(value), allowedVariance); + } + + [Theory] + [InlineData( double.NegativeInfinity, double.NaN, 0.0)] + [InlineData(-3.1415926535897932, double.NaN, 0.0)] // value: -(pi) + [InlineData(-2.7182818284590452, double.NaN, 0.0)] // value: -(e) + [InlineData(-1.4142135623730950, double.NaN, 0.0)] // value: -(sqrt(2)) + [InlineData( double.NaN, double.NaN, 0.0)] + [InlineData(-1.0, double.NegativeInfinity, 0.0)] + [InlineData(-0.99808698589777568, -2.7182818284590452, CrossPlatformMachineEpsilon * 10)] // expected: -(e) + [InlineData(-0.99501787170355928, -2.3025850929940457, CrossPlatformMachineEpsilon * 10)] // expected: -(ln(10)) + [InlineData(-0.97313395899886387, -1.5707963267948966, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(-0.96391680717921279, -1.4426950408889634, CrossPlatformMachineEpsilon * 10)] // expected: -(log2(e)) + [InlineData(-0.96147111529967797, -1.4142135623730950, CrossPlatformMachineEpsilon * 10)] // expected: -(sqrt(2)) + [InlineData(-0.92559179413935728, -1.1283791670955126, CrossPlatformMachineEpsilon * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(-0.9, -1.0, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.83609136386042335, -0.78539816339744831, CrossPlatformMachineEpsilon)] // expected: -(pi / 4) + [InlineData(-0.80371224006494438, -0.70710678118654752, CrossPlatformMachineEpsilon)] // expected: -(1 / sqrt(2)) + [InlineData(-0.79730043371348270, -0.69314718055994531, CrossPlatformMachineEpsilon)] // expected: -(ln(2)) + [InlineData(-0.76912323548399945, -0.63661977236758134, CrossPlatformMachineEpsilon)] // expected: -(2 / pi) + [InlineData(-0.63212055882855768, -0.43429448190325183, CrossPlatformMachineEpsilon)] // expected: -(log10(e)) + [InlineData(-0.51950362694813132, -0.31830988618379067, CrossPlatformMachineEpsilon)] // expected: -(1 / pi) + [InlineData(-0.0, 0.0, 0.0)] + [InlineData( 0.0, 0.0, 0.0)] + [InlineData( 1.0811811619898573, 0.31830988618379067, CrossPlatformMachineEpsilon)] // expected: (1 / pi) + [InlineData( 1.7182818284590452, 0.43429448190325183, CrossPlatformMachineEpsilon)] // expected: (log10(e)) value: (e) + [InlineData( 3.3313150290214525, 0.63661977236758134, CrossPlatformMachineEpsilon)] // expected: (2 / pi) + [InlineData( 3.9334096679145963, 0.69314718055994531, CrossPlatformMachineEpsilon)] // expected: (ln(2)) + [InlineData( 4.0945611704512962, 0.70710678118654752, CrossPlatformMachineEpsilon)] // expected: (1 / sqrt(2)) + [InlineData( 5.1009598002416937, 0.78539816339744831, CrossPlatformMachineEpsilon)] // expected: (pi / 4) + [InlineData( 9.0, 1.0, CrossPlatformMachineEpsilon * 10)] + [InlineData( 12.439377934644401, 1.1283791670955126, CrossPlatformMachineEpsilon * 10)] // expected: (2 / sqrt(pi)) + [InlineData( 24.954553519470081, 1.4142135623730950, CrossPlatformMachineEpsilon * 10)] // expected: (sqrt(2)) + [InlineData( 26.713733786437790, 1.4426950408889634, CrossPlatformMachineEpsilon * 10)] // expected: (log2(e)) + [InlineData( 36.221710484165167, 1.5707963267948966, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData( 199.71743249053009, 2.3025850929940457, CrossPlatformMachineEpsilon * 10)] // expected: (ln(10)) + [InlineData( 521.73529967043665, 2.7182818284590452, CrossPlatformMachineEpsilon * 10)] // expected: (e) + [InlineData( 1384.4557313670111, 3.1415926535897932, CrossPlatformMachineEpsilon * 10)] // expected: (pi) + [InlineData( double.PositiveInfinity, double.PositiveInfinity, 0.0)] + public static void Log10P1Test(double value, double expectedResult, double allowedVariance) + { + AssertExtensions.Equal(expectedResult, double.Log10P1(value), allowedVariance); + } } } diff --git a/src/libraries/System.Runtime/tests/System/HalfTests.cs b/src/libraries/System.Runtime/tests/System/HalfTests.cs index fa1f84e34dadf9..9970f291eaf5e7 100644 --- a/src/libraries/System.Runtime/tests/System/HalfTests.cs +++ b/src/libraries/System.Runtime/tests/System/HalfTests.cs @@ -4,12 +4,25 @@ using System.Collections.Generic; using System.Globalization; using Xunit; -using Xunit.Sdk; namespace System.Tests { public partial class HalfTests { + // binary32 (float) has a machine epsilon of 2^-10 (approx. 9.77e-04). However, this + // is slightly too accurate when writing tests meant to run against libm implementations + // for various platforms. 2^-8 (approx. 3.91e-03) seems to be as accurate as we can get. + // + // The tests themselves will take CrossPlatformMachineEpsilon and adjust it according to the expected result + // so that the delta used for comparison will compare the most significant digits and ignore + // any digits that are outside the half precision range (3-4 digits). + // + // For example, a test with an expect result in the format of 0.xxxxxxxxx will use + // CrossPlatformMachineEpsilon for the variance, while an expected result in the format of 0.0xxxxxxxxx + // will use CrossPlatformMachineEpsilon / 10 and expected result in the format of x.xxxxxx will + // use CrossPlatformMachineEpsilon * 10. + private static Half CrossPlatformMachineEpsilon => (Half)3.90625e-03f; + [Fact] public static void Epsilon() { @@ -1212,5 +1225,363 @@ public static void MinNumberTest(Half x, Half y, Half expectedResult) { AssertExtensions.Equal(expectedResult, Half.MinNumber(x, y), (Half)0.0f); } + + public static IEnumerable ExpM1_TestData() + { + yield return new object[] { Half.NegativeInfinity, (Half)(-1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)(-3.14159265f), (Half)(-0.956786082f), CrossPlatformMachineEpsilon }; // value: -(pi) + yield return new object[] { (Half)(-2.71828183f), (Half)(-0.934011964f), CrossPlatformMachineEpsilon }; // value: -(e) + yield return new object[] { (Half)(-2.30258509f), (Half)(-0.9f), CrossPlatformMachineEpsilon }; // value: -(ln(10)) + yield return new object[] { (Half)(-1.57079633f), (Half)(-0.792120424f), CrossPlatformMachineEpsilon }; // value: -(pi / 2) + yield return new object[] { (Half)(-1.44269504f), (Half)(-0.763709912f), CrossPlatformMachineEpsilon }; // value: -(log2(e)) + yield return new object[] { (Half)(-1.41421356f), (Half)(-0.756883266f), CrossPlatformMachineEpsilon }; // value: -(sqrt(2)) + yield return new object[] { (Half)(-1.12837917f), (Half)(-0.676442736f), CrossPlatformMachineEpsilon }; // value: -(2 / sqrt(pi)) + yield return new object[] { (Half)(-1.0f), (Half)(-0.632120559f), CrossPlatformMachineEpsilon }; + yield return new object[] { (Half)(-0.785398163f), (Half)(-0.544061872f), CrossPlatformMachineEpsilon }; // value: -(pi / 4) + yield return new object[] { (Half)(-0.707106781f), (Half)(-0.506931309f), CrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2)) + yield return new object[] { (Half)(-0.693147181f), (Half)(-0.5f), CrossPlatformMachineEpsilon }; // value: -(ln(2)) + yield return new object[] { (Half)(-0.636619772f), (Half)(-0.470922192f), CrossPlatformMachineEpsilon }; // value: -(2 / pi) + yield return new object[] { (Half)(-0.434294482f), (Half)(-0.352278515f), CrossPlatformMachineEpsilon }; // value: -(log10(e)) + yield return new object[] { (Half)(-0.318309886f), (Half)(-0.272622651f), CrossPlatformMachineEpsilon }; // value: -(1 / pi) + yield return new object[] { (Half)(-0.0f), (Half)( 0.0f), (Half)0.0f }; + yield return new object[] { Half.NaN, Half.NaN, (Half)0.0f }; + yield return new object[] { (Half)( 0.0f), (Half)( 0.0f), (Half)0.0f }; + yield return new object[] { (Half)( 0.318309886f), (Half)( 0.374802227f), CrossPlatformMachineEpsilon }; // value: (1 / pi) + yield return new object[] { (Half)( 0.434294482f), (Half)( 0.543873444f), CrossPlatformMachineEpsilon }; // value: (log10(e)) + yield return new object[] { (Half)( 0.636619772f), (Half)( 0.890081165f), CrossPlatformMachineEpsilon }; // value: (2 / pi) + yield return new object[] { (Half)( 0.693147181f), (Half)( 1.0f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (ln(2)) + yield return new object[] { (Half)( 0.707106781f), (Half)( 1.02811498f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (1 / sqrt(2)) + yield return new object[] { (Half)( 0.785398163f), (Half)( 1.19328005f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (pi / 4) + yield return new object[] { (Half)( 1.0f), (Half)( 1.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)( 1.12837917f), (Half)( 2.09064302f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (2 / sqrt(pi)) + yield return new object[] { (Half)( 1.41421356f), (Half)( 3.11325038f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (sqrt(2)) + yield return new object[] { (Half)( 1.44269504f), (Half)( 3.23208611f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (log2(e)) + yield return new object[] { (Half)( 1.57079633f), (Half)( 3.81047738f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (pi / 2) + yield return new object[] { (Half)( 2.30258509f), (Half)( 9.0f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (ln(10)) + yield return new object[] { (Half)( 2.71828183f), (Half)( 14.1542622f), CrossPlatformMachineEpsilon * (Half)100 }; // value: (e) + yield return new object[] { (Half)( 3.14159265f), (Half)( 22.1406926f), CrossPlatformMachineEpsilon * (Half)100 }; // value: (pi) + yield return new object[] { Half.PositiveInfinity, Half.PositiveInfinity, 0.0 }; + } + + [Theory] + [MemberData(nameof(ExpM1_TestData))] + public static void ExpM1Test(Half value, Half expectedResult, Half allowedVariance) + { + AssertExtensions.Equal(expectedResult, Half.ExpM1(value), allowedVariance); + } + + public static IEnumerable Exp2_TestData() + { + yield return new object[] { Half.NegativeInfinity, (Half)(0.0f), (Half)0.0f }; + yield return new object[] { (Half)(-3.14159265f), (Half)(0.113314732f), CrossPlatformMachineEpsilon }; // value: -(pi) + yield return new object[] { (Half)(-2.71828183f), (Half)(0.151955223f), CrossPlatformMachineEpsilon }; // value: -(e) + yield return new object[] { (Half)(-2.30258509f), (Half)(0.202699566f), CrossPlatformMachineEpsilon }; // value: -(ln(10)) + yield return new object[] { (Half)(-1.57079633f), (Half)(0.336622537f), CrossPlatformMachineEpsilon }; // value: -(pi / 2) + yield return new object[] { (Half)(-1.44269504f), (Half)(0.367879441f), CrossPlatformMachineEpsilon }; // value: -(log2(e)) + yield return new object[] { (Half)(-1.41421356f), (Half)(0.375214227f), CrossPlatformMachineEpsilon }; // value: -(sqrt(2)) + yield return new object[] { (Half)(-1.12837917f), (Half)(0.457429347f), CrossPlatformMachineEpsilon }; // value: -(2 / sqrt(pi)) + yield return new object[] { (Half)(-1.0f), (Half)(0.5f), CrossPlatformMachineEpsilon }; + yield return new object[] { (Half)(-0.785398163f), (Half)(0.580191810f), CrossPlatformMachineEpsilon }; // value: -(pi / 4) + yield return new object[] { (Half)(-0.707106781f), (Half)(0.612547327f), CrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2)) + yield return new object[] { (Half)(-0.693147181f), (Half)(0.618503138f), CrossPlatformMachineEpsilon }; // value: -(ln(2)) + yield return new object[] { (Half)(-0.636619772f), (Half)(0.643218242f), CrossPlatformMachineEpsilon }; // value: -(2 / pi) + yield return new object[] { (Half)(-0.434294482f), (Half)(0.740055574f), CrossPlatformMachineEpsilon }; // value: -(log10(e)) + yield return new object[] { (Half)(-0.318309886f), (Half)(0.802008879f), CrossPlatformMachineEpsilon }; // value: -(1 / pi) + yield return new object[] { (Half)(-0.0f), (Half)(1.0f), (Half)0.0f }; + yield return new object[] { Half.NaN, Half.NaN, (Half)0.0f }; + yield return new object[] { (Half)( 0.0f), (Half)(1.0f), (Half)0.0f }; + yield return new object[] { (Half)( 0.318309886f), (Half)(1.24686899f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (1 / pi) + yield return new object[] { (Half)( 0.434294482f), (Half)(1.35124987f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (log10(e)) + yield return new object[] { (Half)( 0.636619772f), (Half)(1.55468228f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (2 / pi) + yield return new object[] { (Half)( 0.693147181f), (Half)(1.61680667f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (ln(2)) + yield return new object[] { (Half)( 0.707106781f), (Half)(1.63252692f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (1 / sqrt(2)) + yield return new object[] { (Half)( 0.785398163f), (Half)(1.72356793f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (pi / 4) + yield return new object[] { (Half)( 1.0f), (Half)(2.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)( 1.12837917f), (Half)(2.18612996f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (2 / sqrt(pi)) + yield return new object[] { (Half)( 1.41421356f), (Half)(2.66514414f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (sqrt(2)) + yield return new object[] { (Half)( 1.44269504f), (Half)(2.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (log2(e)) + yield return new object[] { (Half)( 1.57079633f), (Half)(2.97068642f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (pi / 2) + yield return new object[] { (Half)( 2.30258509f), (Half)(4.93340967f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (ln(10)) + yield return new object[] { (Half)( 2.71828183f), (Half)(6.58088599f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (e) + yield return new object[] { (Half)( 3.14159265f), (Half)(8.82497783f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (pi) + yield return new object[] { Half.PositiveInfinity, Half.PositiveInfinity, 0.0f }; + } + + [Theory] + [MemberData(nameof(Exp2_TestData))] + public static void Exp2Test(Half value, Half expectedResult, Half allowedVariance) + { + AssertExtensions.Equal(expectedResult, Half.Exp2(value), allowedVariance); + } + + public static IEnumerable Exp2M1_TestData() + { + yield return new object[] { Half.NegativeInfinity, (Half)(-1.0f), (Half)0.0f }; + yield return new object[] { (Half)(-3.14159265f), (Half)(-0.886685268f), CrossPlatformMachineEpsilon }; // value: -(pi) + yield return new object[] { (Half)(-2.71828183f), (Half)(-0.848044777f), CrossPlatformMachineEpsilon }; // value: -(e) + yield return new object[] { (Half)(-2.30258509f), (Half)(-0.797300434f), CrossPlatformMachineEpsilon }; // value: -(ln(10)) + yield return new object[] { (Half)(-1.57079633f), (Half)(-0.663377463f), CrossPlatformMachineEpsilon }; // value: -(pi / 2) + yield return new object[] { (Half)(-1.44269504f), (Half)(-0.632120559f), CrossPlatformMachineEpsilon }; // value: -(log2(e)) + yield return new object[] { (Half)(-1.41421356f), (Half)(-0.624785773f), CrossPlatformMachineEpsilon }; // value: -(sqrt(2)) + yield return new object[] { (Half)(-1.12837917f), (Half)(-0.542570653f), CrossPlatformMachineEpsilon }; // value: -(2 / sqrt(pi)) + yield return new object[] { (Half)(-1.0f), (Half)(-0.5f), CrossPlatformMachineEpsilon }; + yield return new object[] { (Half)(-0.785398163f), (Half)(-0.419808190f), CrossPlatformMachineEpsilon }; // value: -(pi / 4) + yield return new object[] { (Half)(-0.707106781f), (Half)(-0.387452673f), CrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2)) + yield return new object[] { (Half)(-0.693147181f), (Half)(-0.381496862f), CrossPlatformMachineEpsilon }; // value: -(ln(2)) + yield return new object[] { (Half)(-0.636619772f), (Half)(-0.356781758f), CrossPlatformMachineEpsilon }; // value: -(2 / pi) + yield return new object[] { (Half)(-0.434294482f), (Half)(-0.259944426f), CrossPlatformMachineEpsilon }; // value: -(log10(e)) + yield return new object[] { (Half)(-0.318309886f), (Half)(-0.197991121f), CrossPlatformMachineEpsilon }; // value: -(1 / pi) + yield return new object[] { (Half)(-0.0f), (Half)( 0.0f), (Half)0.0f }; + yield return new object[] { Half.NaN, Half.NaN, (Half)0.0f }; + yield return new object[] { (Half)( 0.0f), (Half)( 0.0f), (Half)0.0f }; + yield return new object[] { (Half)( 0.318309886f), (Half)( 0.246868989f), CrossPlatformMachineEpsilon }; // value: (1 / pi) + yield return new object[] { (Half)( 0.434294482f), (Half)( 0.351249873f), CrossPlatformMachineEpsilon }; // value: (log10(e)) + yield return new object[] { (Half)( 0.636619772f), (Half)( 0.554682275f), CrossPlatformMachineEpsilon }; // value: (2 / pi) + yield return new object[] { (Half)( 0.693147181f), (Half)( 0.616806672f), CrossPlatformMachineEpsilon }; // value: (ln(2)) + yield return new object[] { (Half)( 0.707106781f), (Half)( 0.632526919f), CrossPlatformMachineEpsilon }; // value: (1 / sqrt(2)) + yield return new object[] { (Half)( 0.785398163f), (Half)( 0.723567934f), CrossPlatformMachineEpsilon }; // value: (pi / 4) + yield return new object[] { (Half)( 1.0f), (Half)( 1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)( 1.12837917f), (Half)( 1.18612996f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (2 / sqrt(pi)) + yield return new object[] { (Half)( 1.41421356f), (Half)( 1.66514414f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (sqrt(2)) + yield return new object[] { (Half)( 1.44269504f), (Half)( 1.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (log2(e)) + yield return new object[] { (Half)( 1.57079633f), (Half)( 1.97068642f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (pi / 2) + yield return new object[] { (Half)( 2.30258509f), (Half)( 3.93340967f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (ln(10)) + yield return new object[] { (Half)( 2.71828183f), (Half)( 5.58088599f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (e) + yield return new object[] { (Half)( 3.14159265f), (Half)( 7.82497783f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (pi) + yield return new object[] { Half.PositiveInfinity, Half.PositiveInfinity, (Half)0.0f }; + } + + [Theory] + [MemberData(nameof(Exp2M1_TestData))] + public static void Exp2M1Test(Half value, Half expectedResult, Half allowedVariance) + { + AssertExtensions.Equal(expectedResult, Half.Exp2M1(value), allowedVariance); + } + + public static IEnumerable Exp10_TestData() + { + yield return new object[] { Half.NegativeInfinity, (Half)0.0f, (Half)0.0f }; + yield return new object[] { (Half)(-3.14159265f), (Half)0.000721784159f, CrossPlatformMachineEpsilon / (Half)1000 }; // value: -(pi) + yield return new object[] { (Half)(-2.71828183f), (Half)0.00191301410f, CrossPlatformMachineEpsilon / (Half)100 }; // value: -(e) + yield return new object[] { (Half)(-2.30258509f), (Half)0.00498212830f, CrossPlatformMachineEpsilon / (Half)100 }; // value: -(ln(10)) + yield return new object[] { (Half)(-1.57079633f), (Half)0.0268660410f, CrossPlatformMachineEpsilon / (Half)10 }; // value: -(pi / 2) + yield return new object[] { (Half)(-1.44269504f), (Half)0.0360831928f, CrossPlatformMachineEpsilon / (Half)10 }; // value: -(log2(e)) + yield return new object[] { (Half)(-1.41421356f), (Half)0.0385288847f, CrossPlatformMachineEpsilon / (Half)10 }; // value: -(sqrt(2)) + yield return new object[] { (Half)(-1.12837917f), (Half)0.0744082059f, CrossPlatformMachineEpsilon / (Half)10 }; // value: -(2 / sqrt(pi)) + yield return new object[] { (Half)(-1.0f), (Half)0.1f, CrossPlatformMachineEpsilon }; + yield return new object[] { (Half)(-0.785398163f), (Half)0.163908636f, CrossPlatformMachineEpsilon }; // value: -(pi / 4) + yield return new object[] { (Half)(-0.707106781f), (Half)0.196287760f, CrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2)) + yield return new object[] { (Half)(-0.693147181f), (Half)0.202699566f, CrossPlatformMachineEpsilon }; // value: -(ln(2)) + yield return new object[] { (Half)(-0.636619772f), (Half)0.230876765f, CrossPlatformMachineEpsilon }; // value: -(2 / pi) + yield return new object[] { (Half)(-0.434294482f), (Half)0.367879441f, CrossPlatformMachineEpsilon }; // value: -(log10(e)) + yield return new object[] { (Half)(-0.318309886f), (Half)0.480496373f, CrossPlatformMachineEpsilon }; // value: -(1 / pi) + yield return new object[] { (Half)(-0.0f), (Half)1.0f, (Half)0.0f }; + yield return new object[] { Half.NaN, Half.NaN, (Half)0.0f }; + yield return new object[] { (Half)( 0.0f), (Half)1.0f, (Half)0.0f }; + yield return new object[] { (Half)( 0.318309886f), (Half)2.08118116f, CrossPlatformMachineEpsilon * (Half)10 }; // value: (1 / pi) + yield return new object[] { (Half)( 0.434294482f), (Half)2.71828183f, CrossPlatformMachineEpsilon * (Half)10 }; // value: (log10(e)) + yield return new object[] { (Half)( 0.636619772f), (Half)4.33131503f, CrossPlatformMachineEpsilon * (Half)10 }; // value: (2 / pi) + yield return new object[] { (Half)( 0.693147181f), (Half)4.93340967f, CrossPlatformMachineEpsilon * (Half)10 }; // value: (ln(2)) + yield return new object[] { (Half)( 0.707106781f), (Half)5.09456117f, CrossPlatformMachineEpsilon * (Half)10 }; // value: (1 / sqrt(2)) + yield return new object[] { (Half)( 0.785398163f), (Half)6.10095980f, CrossPlatformMachineEpsilon * (Half)10 }; // value: (pi / 4) + yield return new object[] { (Half)( 1.0f), (Half)10.0f, CrossPlatformMachineEpsilon * (Half)100 }; + yield return new object[] { (Half)( 1.12837917f), (Half)13.4393779f, CrossPlatformMachineEpsilon * (Half)100 }; // value: (2 / sqrt(pi)) + yield return new object[] { (Half)( 1.41421356f), (Half)25.9545535f, CrossPlatformMachineEpsilon * (Half)100 }; // value: (sqrt(2)) + yield return new object[] { (Half)( 1.44269504f), (Half)27.7137338f, CrossPlatformMachineEpsilon * (Half)100 }; // value: (log2(e)) + yield return new object[] { (Half)( 1.57079633f), (Half)37.2217105f, CrossPlatformMachineEpsilon * (Half)100 }; // value: (pi / 2) + yield return new object[] { (Half)( 2.30258509f), (Half)200.717432f, CrossPlatformMachineEpsilon * (Half)1000 }; // value: (ln(10)) + yield return new object[] { (Half)( 2.71828183f), (Half)522.735300f, CrossPlatformMachineEpsilon * (Half)1000 }; // value: (e) + yield return new object[] { (Half)( 3.14159265f), (Half)1385.45573f, CrossPlatformMachineEpsilon * (Half)10000 }; // value: (pi) + yield return new object[] { Half.PositiveInfinity, Half.PositiveInfinity, (Half)0.0f }; + } + + [Theory] + [MemberData(nameof(Exp10_TestData))] + public static void Exp10Test(Half value, Half expectedResult, Half allowedVariance) + { + AssertExtensions.Equal(expectedResult, Half.Exp10(value), allowedVariance); + } + + public static IEnumerable Exp10M1_TestData() + { + yield return new object[] { Half.NegativeInfinity, (Half)(-1.0f), (Half)0.0f }; + yield return new object[] { (Half)(-3.14159265f), (Half)(-0.999278216f), CrossPlatformMachineEpsilon }; // value: -(pi) + yield return new object[] { (Half)(-2.71828183f), (Half)(-0.998086986f), CrossPlatformMachineEpsilon }; // value: -(e) + yield return new object[] { (Half)(-2.30258509f), (Half)(-0.995017872f), CrossPlatformMachineEpsilon }; // value: -(ln(10)) + yield return new object[] { (Half)(-1.57079633f), (Half)(-0.973133959f), CrossPlatformMachineEpsilon }; // value: -(pi / 2) + yield return new object[] { (Half)(-1.44269504f), (Half)(-0.963916807f), CrossPlatformMachineEpsilon }; // value: -(log2(e)) + yield return new object[] { (Half)(-1.41421356f), (Half)(-0.961471115f), CrossPlatformMachineEpsilon }; // value: -(sqrt(2)) + yield return new object[] { (Half)(-1.12837917f), (Half)(-0.925591794f), CrossPlatformMachineEpsilon }; // value: -(2 / sqrt(pi)) + yield return new object[] { (Half)(-1.0f), (Half)(-0.9f), CrossPlatformMachineEpsilon }; + yield return new object[] { (Half)(-0.785398163f), (Half)(-0.836091364f), CrossPlatformMachineEpsilon }; // value: -(pi / 4) + yield return new object[] { (Half)(-0.707106781f), (Half)(-0.803712240f), CrossPlatformMachineEpsilon }; // value: -(1 / sqrt(2)) + yield return new object[] { (Half)(-0.693147181f), (Half)(-0.797300434f), CrossPlatformMachineEpsilon }; // value: -(ln(2)) + yield return new object[] { (Half)(-0.636619772f), (Half)(-0.769123235f), CrossPlatformMachineEpsilon }; // value: -(2 / pi) + yield return new object[] { (Half)(-0.434294482f), (Half)(-0.632120559f), CrossPlatformMachineEpsilon }; // value: -(log10(e)) + yield return new object[] { (Half)(-0.318309886f), (Half)(-0.519503627f), CrossPlatformMachineEpsilon }; // value: -(1 / pi) + yield return new object[] { (Half)(-0.0f), (Half)( 0.0f), (Half)0.0f }; + yield return new object[] { Half.NaN, Half.NaN, (Half)0.0f }; + yield return new object[] { (Half)( 0.0f), (Half)( 0.0f), (Half)0.0f }; + yield return new object[] { (Half)( 0.318309886f), (Half)( 1.08118116f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (1 / pi) + yield return new object[] { (Half)( 0.434294482f), (Half)( 1.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (log10(e)) + yield return new object[] { (Half)( 0.636619772f), (Half)( 3.33131503f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (2 / pi) + yield return new object[] { (Half)( 0.693147181f), (Half)( 3.93340967f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (ln(2)) + yield return new object[] { (Half)( 0.707106781f), (Half)( 4.09456117f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (1 / sqrt(2)) + yield return new object[] { (Half)( 0.785398163f), (Half)( 5.10095980f), CrossPlatformMachineEpsilon * (Half)10 }; // value: (pi / 4) + yield return new object[] { (Half)( 1.0f), (Half)( 9.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)( 1.12837917f), (Half)( 12.4393779f), CrossPlatformMachineEpsilon * (Half)100 }; // value: (2 / sqrt(pi)) + yield return new object[] { (Half)( 1.41421356f), (Half)( 24.9545535f), CrossPlatformMachineEpsilon * (Half)100 }; // value: (sqrt(2)) + yield return new object[] { (Half)( 1.44269504f), (Half)( 26.7137338f), CrossPlatformMachineEpsilon * (Half)100 }; // value: (log2(e)) + yield return new object[] { (Half)( 1.57079633f), (Half)( 36.2217105f), CrossPlatformMachineEpsilon * (Half)100 }; // value: (pi / 2) + yield return new object[] { (Half)( 2.30258509f), (Half)( 199.717432f), CrossPlatformMachineEpsilon * (Half)1000 }; // value: (ln(10)) + yield return new object[] { (Half)( 2.71828183f), (Half)( 521.735300f), CrossPlatformMachineEpsilon * (Half)1000 }; // value: (e) + yield return new object[] { (Half)( 3.14159265f), (Half)( 1384.45573f), CrossPlatformMachineEpsilon * (Half)10000 }; // value: (pi) + yield return new object[] { Half.PositiveInfinity, Half.PositiveInfinity, (Half)0.0f }; + } + + [Theory] + [MemberData(nameof(Exp10M1_TestData))] + public static void Exp10M1Test(Half value, Half expectedResult, Half allowedVariance) + { + AssertExtensions.Equal(expectedResult, Half.Exp10M1(value), allowedVariance); + } + + public static IEnumerable LogP1_TestData() + { + yield return new object[] { Half.NegativeInfinity, Half.NaN, (Half)0.0f }; + yield return new object[] { (Half)(-3.14159265f), Half.NaN, (Half)0.0f }; // value: -(pi) + yield return new object[] { (Half)(-2.71828183f), Half.NaN, (Half)0.0f }; // value: -(e) + yield return new object[] { (Half)(-1.41421356f), Half.NaN, (Half)0.0f }; // value: -(sqrt(2)) + yield return new object[] { Half.NaN, Half.NaN, (Half)0.0f }; + yield return new object[] { (Half)(-1.0f), Half.NegativeInfinity, (Half)0.0f }; + yield return new object[] { (Half)(-0.956786082f), (Half)(-3.14159265f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(pi) + yield return new object[] { (Half)(-0.934011964f), (Half)(-2.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(e) + yield return new object[] { (Half)(-0.9f), (Half)(-2.30258509f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(ln(10)) + yield return new object[] { (Half)(-0.792120424f), (Half)(-1.57079633f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(pi / 2) + yield return new object[] { (Half)(-0.763709912f), (Half)(-1.44269504f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(log2(e)) + yield return new object[] { (Half)(-0.756883266f), (Half)(-1.41421356f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(sqrt(2)) + yield return new object[] { (Half)(-0.676442736f), (Half)(-1.12837917f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(2 / sqrt(pi)) + yield return new object[] { (Half)(-0.632120559f), (Half)(-1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)(-0.544061872f), (Half)(-0.785398163f), CrossPlatformMachineEpsilon }; // expected: -(pi / 4) + yield return new object[] { (Half)(-0.506931309f), (Half)(-0.707106781f), CrossPlatformMachineEpsilon }; // expected: -(1 / sqrt(2)) + yield return new object[] { (Half)(-0.5f), (Half)(-0.693147181f), CrossPlatformMachineEpsilon }; // expected: -(ln(2)) + yield return new object[] { (Half)(-0.470922192f), (Half)(-0.636619772f), CrossPlatformMachineEpsilon }; // expected: -(2 / pi) + yield return new object[] { (Half)(-0.0f), (Half)( 0.0f), 0.0f }; + yield return new object[] { (Half)( 0.0f), (Half)( 0.0f), 0.0f }; + yield return new object[] { (Half)( 0.374802227f), (Half)( 0.318309886f), CrossPlatformMachineEpsilon }; // expected: (1 / pi) + yield return new object[] { (Half)( 0.543873444f), (Half)( 0.434294482f), CrossPlatformMachineEpsilon }; // expected: (log10(e)) + yield return new object[] { (Half)( 0.890081165f), (Half)( 0.636619772f), CrossPlatformMachineEpsilon }; // expected: (2 / pi) + yield return new object[] { (Half)( 1.0f), (Half)( 0.693147181f), CrossPlatformMachineEpsilon }; // expected: (ln(2)) + yield return new object[] { (Half)( 1.02811498f), (Half)( 0.707106781f), CrossPlatformMachineEpsilon }; // expected: (1 / sqrt(2)) + yield return new object[] { (Half)( 1.19328005f), (Half)( 0.785398163f), CrossPlatformMachineEpsilon }; // expected: (pi / 4) + yield return new object[] { (Half)( 1.71828183f), (Half)( 1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)( 2.09064302f), (Half)( 1.12837917f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (2 / sqrt(pi)) + yield return new object[] { (Half)( 3.11325038f), (Half)( 1.41421356f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (sqrt(2)) + yield return new object[] { (Half)( 3.23208611f), (Half)( 1.44269504f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (log2(e)) + yield return new object[] { (Half)( 3.81047738f), (Half)( 1.57079633f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (pi / 2) + yield return new object[] { (Half)( 9.0f), (Half)( 2.30258509f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (ln(10)) + yield return new object[] { (Half)( 14.1542622f), (Half)( 2.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (e) + yield return new object[] { (Half)( 22.1406926f), (Half)( 3.14159265f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (pi) + yield return new object[] { Half.PositiveInfinity, Half.PositiveInfinity, (Half)0.0f }; + } + + [Theory] + [MemberData(nameof(LogP1_TestData))] + public static void LogP1Test(Half value, Half expectedResult, Half allowedVariance) + { + AssertExtensions.Equal(expectedResult, Half.LogP1(value), allowedVariance); + } + + public static IEnumerable Log2P1_TestData() + { + yield return new object[] { Half.NegativeInfinity, Half.NaN, (Half)0.0f }; + yield return new object[] { Half.NaN, Half.NaN, (Half)0.0f }; + yield return new object[] { (Half)(-1.0f), Half.NegativeInfinity, (Half)0.0f }; + yield return new object[] { (Half)(-0.886685268f), (Half)(-3.14159265f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(pi) + yield return new object[] { (Half)(-0.848044777f), (Half)(-2.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(e) + yield return new object[] { (Half)(-0.797300434f), (Half)(-2.30258509f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(ln(10)) + yield return new object[] { (Half)(-0.663377463f), (Half)(-1.57079633f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(pi / 2) + yield return new object[] { (Half)(-0.632120559f), (Half)(-1.44269504f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(log2(e)) + yield return new object[] { (Half)(-0.624785773f), (Half)(-1.41421356f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(sqrt(2)) + yield return new object[] { (Half)(-0.542570653f), (Half)(-1.12837917f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(2 / sqrt(pi)) + yield return new object[] { (Half)(-0.5f), (Half)(-1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)(-0.419808190f), (Half)(-0.785398163f), CrossPlatformMachineEpsilon }; // expected: -(pi / 4) + yield return new object[] { (Half)(-0.387452673f), (Half)(-0.707106781f), CrossPlatformMachineEpsilon }; // expected: -(1 / sqrt(2)) + yield return new object[] { (Half)(-0.381496862f), (Half)(-0.693147181f), CrossPlatformMachineEpsilon }; // expected: -(ln(2)) + yield return new object[] { (Half)(-0.356781758f), (Half)(-0.636619772f), CrossPlatformMachineEpsilon }; // expected: -(2 / pi) + yield return new object[] { (Half)(-0.259944426f), (Half)(-0.434294482f), CrossPlatformMachineEpsilon }; // expected: -(log10(e)) + yield return new object[] { (Half)(-0.197991121f), (Half)(-0.318309886f), CrossPlatformMachineEpsilon }; // expected: -(1 / pi) + yield return new object[] { (Half)(-0.0f), (Half)( 0.0f), (Half)0.0f }; + yield return new object[] { (Half)( 0.0f), (Half)( 0.0f), (Half)0.0f }; + yield return new object[] { (Half)( 0.246868989f), (Half)( 0.318309886f), CrossPlatformMachineEpsilon }; // expected: (1 / pi) + yield return new object[] { (Half)( 0.351249873f), (Half)( 0.434294482f), CrossPlatformMachineEpsilon }; // expected: (log10(e)) + yield return new object[] { (Half)( 0.554682275f), (Half)( 0.636619772f), CrossPlatformMachineEpsilon }; // expected: (2 / pi) + yield return new object[] { (Half)( 0.616806672f), (Half)( 0.693147181f), CrossPlatformMachineEpsilon }; // expected: (ln(2)) + yield return new object[] { (Half)( 0.632526919f), (Half)( 0.707106781f), CrossPlatformMachineEpsilon }; // expected: (1 / sqrt(2)) + yield return new object[] { (Half)( 0.723567934f), (Half)( 0.785398163f), CrossPlatformMachineEpsilon }; // expected: (pi / 4) + yield return new object[] { (Half)( 1.0f), (Half)( 1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)( 1.18612996f), (Half)( 1.12837917f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (2 / sqrt(pi)) + yield return new object[] { (Half)( 1.66514414f), (Half)( 1.41421356f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (sqrt(2)) + yield return new object[] { (Half)( 1.71828183f), (Half)( 1.44269504f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (log2(e)) + yield return new object[] { (Half)( 1.97068642f), (Half)( 1.57079633f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (pi / 2) + yield return new object[] { (Half)( 3.93340967f), (Half)( 2.30258509f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (ln(10)) + yield return new object[] { (Half)( 5.58088599f), (Half)( 2.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (e) + yield return new object[] { (Half)( 7.82497783f), (Half)( 3.14159265f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (pi) + yield return new object[] { Half.PositiveInfinity, Half.PositiveInfinity, (Half)0.0f }; + } + + [Theory] + [MemberData(nameof(Log2P1_TestData))] + public static void Log2P1Test(Half value, Half expectedResult, Half allowedVariance) + { + AssertExtensions.Equal(expectedResult, Half.Log2P1(value), allowedVariance); + } + + public static IEnumerable Log10P1_TestData() + { + yield return new object[] { Half.NegativeInfinity, Half.NaN, (Half)0.0f }; + yield return new object[] { (Half)(-3.14159265f), Half.NaN, (Half)0.0f }; // value: -(pi) + yield return new object[] { (Half)(-2.71828183f), Half.NaN, (Half)0.0f }; // value: -(e) + yield return new object[] { (Half)(-1.41421356f), Half.NaN, (Half)0.0f }; // value: -(sqrt(2)) + yield return new object[] { Half.NaN, Half.NaN, (Half)0.0f }; + yield return new object[] { (Half)(-1.0f), Half.NegativeInfinity, (Half)0.0f }; + yield return new object[] { (Half)(-0.998086986f), (Half)(-2.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(e) + yield return new object[] { (Half)(-0.995017872f), (Half)(-2.30258509f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(ln(10)) + yield return new object[] { (Half)(-0.973133959f), (Half)(-1.57079633f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(pi / 2) + yield return new object[] { (Half)(-0.963916807f), (Half)(-1.44269504f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(log2(e)) + yield return new object[] { (Half)(-0.961471115f), (Half)(-1.41421356f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(sqrt(2)) + yield return new object[] { (Half)(-0.925591794f), (Half)(-1.12837917f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: -(2 / sqrt(pi)) + yield return new object[] { (Half)(-0.9f), (Half)(-1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)(-0.836091364f), (Half)(-0.785398163f), CrossPlatformMachineEpsilon }; // expected: -(pi / 4) + yield return new object[] { (Half)(-0.803712240f), (Half)(-0.707106781f), CrossPlatformMachineEpsilon }; // expected: -(1 / sqrt(2)) + yield return new object[] { (Half)(-0.797300434f), (Half)(-0.693147181f), CrossPlatformMachineEpsilon }; // expected: -(ln(2)) + yield return new object[] { (Half)(-0.769123235f), (Half)(-0.636619772f), CrossPlatformMachineEpsilon }; // expected: -(2 / pi) + yield return new object[] { (Half)(-0.632120559f), (Half)(-0.434294482f), CrossPlatformMachineEpsilon }; // expected: -(log10(e)) + yield return new object[] { (Half)(-0.519503627f), (Half)(-0.318309886f), CrossPlatformMachineEpsilon }; // expected: -(1 / pi) + yield return new object[] { (Half)(-0.0f), (Half)( 0.0f), (Half)0.0f }; + yield return new object[] { (Half)( 0.0f), (Half)( 0.0f), (Half)0.0f }; + yield return new object[] { (Half)( 1.08118116f), (Half)( 0.318309886f), CrossPlatformMachineEpsilon }; // expected: (1 / pi) + yield return new object[] { (Half)( 1.71828183f), (Half)( 0.434294482f), CrossPlatformMachineEpsilon }; // expected: (log10(e)) value: (e) + yield return new object[] { (Half)( 3.33131503f), (Half)( 0.636619772f), CrossPlatformMachineEpsilon }; // expected: (2 / pi) + yield return new object[] { (Half)( 3.93340967f), (Half)( 0.693147181f), CrossPlatformMachineEpsilon }; // expected: (ln(2)) + yield return new object[] { (Half)( 4.09456117f), (Half)( 0.707106781f), CrossPlatformMachineEpsilon }; // expected: (1 / sqrt(2)) + yield return new object[] { (Half)( 5.10095980f), (Half)( 0.785398163f), CrossPlatformMachineEpsilon }; // expected: (pi / 4) + yield return new object[] { (Half)( 9.0f), (Half)( 1.0f), CrossPlatformMachineEpsilon * (Half)10 }; + yield return new object[] { (Half)( 12.4393779f), (Half)( 1.12837917f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (2 / sqrt(pi)) + yield return new object[] { (Half)( 24.9545535f), (Half)( 1.41421356f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (sqrt(2)) + yield return new object[] { (Half)( 26.7137338f), (Half)( 1.44269504f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (log2(e)) + yield return new object[] { (Half)( 36.2217105f), (Half)( 1.57079633f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (pi / 2) + yield return new object[] { (Half)( 199.717432f), (Half)( 2.30258509f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (ln(10)) + yield return new object[] { (Half)( 521.735300f), (Half)( 2.71828183f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (e) + yield return new object[] { (Half)( 1384.45573f), (Half)( 3.14159265f), CrossPlatformMachineEpsilon * (Half)10 }; // expected: (pi) + yield return new object[] { Half.PositiveInfinity, Half.PositiveInfinity, (Half)0.0f }; + } + + [Theory] + [MemberData(nameof(Log10P1_TestData))] + public static void Log10P1Test(Half value, Half expectedResult, Half allowedVariance) + { + AssertExtensions.Equal(expectedResult, Half.Log10P1(value), allowedVariance); + } } } diff --git a/src/libraries/System.Runtime/tests/System/SingleTests.cs b/src/libraries/System.Runtime/tests/System/SingleTests.cs index 034916138b7b72..5f28d89c2eaf49 100644 --- a/src/libraries/System.Runtime/tests/System/SingleTests.cs +++ b/src/libraries/System.Runtime/tests/System/SingleTests.cs @@ -13,6 +13,20 @@ public class SingleTests { // NOTE: Consider duplicating any tests added here in DoubleTests.cs + // binary32 (float) has a machine epsilon of 2^-23 (approx. 1.19e-07). However, this + // is slightly too accurate when writing tests meant to run against libm implementations + // for various platforms. 2^-21 (approx. 4.76e-07) seems to be as accurate as we can get. + // + // The tests themselves will take CrossPlatformMachineEpsilon and adjust it according to the expected result + // so that the delta used for comparison will compare the most significant digits and ignore + // any digits that are outside the single precision range (6-9 digits). + // + // For example, a test with an expect result in the format of 0.xxxxxxxxx will use + // CrossPlatformMachineEpsilon for the variance, while an expected result in the format of 0.0xxxxxxxxx + // will use CrossPlatformMachineEpsilon / 10 and expected result in the format of x.xxxxxx will + // use CrossPlatformMachineEpsilon * 10. + private const float CrossPlatformMachineEpsilon = 4.76837158e-07f; + [Theory] [InlineData("a")] [InlineData(234.0)] @@ -838,5 +852,323 @@ public static void MinNumberTest(float x, float y, float expectedResult) { AssertExtensions.Equal(expectedResult, float.MinNumber(x, y), 0.0f); } + + [Theory] + [InlineData( float.NegativeInfinity, -1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-3.14159265f, -0.956786082f, CrossPlatformMachineEpsilon)] // value: -(pi) + [InlineData(-2.71828183f, -0.934011964f, CrossPlatformMachineEpsilon)] // value: -(e) + [InlineData(-2.30258509f, -0.9f, CrossPlatformMachineEpsilon)] // value: -(ln(10)) + [InlineData(-1.57079633f, -0.792120424f, CrossPlatformMachineEpsilon)] // value: -(pi / 2) + [InlineData(-1.44269504f, -0.763709912f, CrossPlatformMachineEpsilon)] // value: -(log2(e)) + [InlineData(-1.41421356f, -0.756883266f, CrossPlatformMachineEpsilon)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, -0.676442736f, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, -0.632120559f, CrossPlatformMachineEpsilon)] + [InlineData(-0.785398163f, -0.544061872f, CrossPlatformMachineEpsilon)] // value: -(pi / 4) + [InlineData(-0.707106781f, -0.506931309f, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, -0.5f, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.636619772f, -0.470922192f, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.434294482f, -0.352278515f, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.318309886f, -0.272622651f, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0f, 0.0f, 0.0f)] + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData( 0.0f, 0.0f, 0.0f)] + [InlineData( 0.318309886f, 0.374802227f, CrossPlatformMachineEpsilon)] // value: (1 / pi) + [InlineData( 0.434294482f, 0.543873444f, CrossPlatformMachineEpsilon)] // value: (log10(e)) + [InlineData( 0.636619772f, 0.890081165f, CrossPlatformMachineEpsilon)] // value: (2 / pi) + [InlineData( 0.693147181f, 1.0f, CrossPlatformMachineEpsilon * 10)] // value: (ln(2)) + [InlineData( 0.707106781f, 1.02811498f, CrossPlatformMachineEpsilon * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.785398163f, 1.19328005f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 4) + [InlineData( 1.0f, 1.71828183f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.12837917f, 2.09064302f, CrossPlatformMachineEpsilon * 10)] // value: (2 / sqrt(pi)) + [InlineData( 1.41421356f, 3.11325038f, CrossPlatformMachineEpsilon * 10)] // value: (sqrt(2)) + [InlineData( 1.44269504f, 3.23208611f, CrossPlatformMachineEpsilon * 10)] // value: (log2(e)) + [InlineData( 1.57079633f, 3.81047738f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2) + [InlineData( 2.30258509f, 9.0f, CrossPlatformMachineEpsilon * 10)] // value: (ln(10)) + [InlineData( 2.71828183f, 14.1542622f, CrossPlatformMachineEpsilon * 100)] // value: (e) + [InlineData( 3.14159265f, 22.1406926f, CrossPlatformMachineEpsilon * 100)] // value: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0)] + public static void ExpM1Test(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, float.ExpM1(value), allowedVariance); + } + + [Theory] + [InlineData( float.NegativeInfinity, 0.0f, 0.0f)] + [InlineData(-3.14159265f, 0.113314732f, CrossPlatformMachineEpsilon)] // value: -(pi) + [InlineData(-2.71828183f, 0.151955223f, CrossPlatformMachineEpsilon)] // value: -(e) + [InlineData(-2.30258509f, 0.202699566f, CrossPlatformMachineEpsilon)] // value: -(ln(10)) + [InlineData(-1.57079633f, 0.336622537f, CrossPlatformMachineEpsilon)] // value: -(pi / 2) + [InlineData(-1.44269504f, 0.367879441f, CrossPlatformMachineEpsilon)] // value: -(log2(e)) + [InlineData(-1.41421356f, 0.375214227f, CrossPlatformMachineEpsilon)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, 0.457429347f, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, 0.5f, CrossPlatformMachineEpsilon)] + [InlineData(-0.785398163f, 0.580191810f, CrossPlatformMachineEpsilon)] // value: -(pi / 4) + [InlineData(-0.707106781f, 0.612547327f, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, 0.618503138f, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.636619772f, 0.643218242f, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.434294482f, 0.740055574f, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.318309886f, 0.802008879f, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0f, 1.0f, 0.0f)] + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData( 0.0f, 1.0f, 0.0f)] + [InlineData( 0.318309886f, 1.24686899f, CrossPlatformMachineEpsilon * 10)] // value: (1 / pi) + [InlineData( 0.434294482f, 1.35124987f, CrossPlatformMachineEpsilon * 10)] // value: (log10(e)) + [InlineData( 0.636619772f, 1.55468228f, CrossPlatformMachineEpsilon * 10)] // value: (2 / pi) + [InlineData( 0.693147181f, 1.61680667f, CrossPlatformMachineEpsilon * 10)] // value: (ln(2)) + [InlineData( 0.707106781f, 1.63252692f, CrossPlatformMachineEpsilon * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.785398163f, 1.72356793f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 4) + [InlineData( 1.0f, 2.0, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.12837917f, 2.18612996f, CrossPlatformMachineEpsilon * 10)] // value: (2 / sqrt(pi)) + [InlineData( 1.41421356f, 2.66514414f, CrossPlatformMachineEpsilon * 10)] // value: (sqrt(2)) + [InlineData( 1.44269504f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // value: (log2(e)) + [InlineData( 1.57079633f, 2.97068642f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2) + [InlineData( 2.30258509f, 4.93340967f, CrossPlatformMachineEpsilon * 10)] // value: (ln(10)) + [InlineData( 2.71828183f, 6.58088599f, CrossPlatformMachineEpsilon * 10)] // value: (e) + [InlineData( 3.14159265f, 8.82497783f, CrossPlatformMachineEpsilon * 10)] // value: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Exp2Test(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, float.Exp2(value), allowedVariance); + } + + [Theory] + [InlineData( float.NegativeInfinity, -1.0f, 0.0f)] + [InlineData(-3.14159265f, -0.886685268f, CrossPlatformMachineEpsilon)] // value: -(pi) + [InlineData(-2.71828183f, -0.848044777f, CrossPlatformMachineEpsilon)] // value: -(e) + [InlineData(-2.30258509f, -0.797300434f, CrossPlatformMachineEpsilon)] // value: -(ln(10)) + [InlineData(-1.57079633f, -0.663377463f, CrossPlatformMachineEpsilon)] // value: -(pi / 2) + [InlineData(-1.44269504f, -0.632120559f, CrossPlatformMachineEpsilon)] // value: -(log2(e)) + [InlineData(-1.41421356f, -0.624785773f, CrossPlatformMachineEpsilon)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, -0.542570653f, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, -0.5f, CrossPlatformMachineEpsilon)] + [InlineData(-0.785398163f, -0.419808190f, CrossPlatformMachineEpsilon)] // value: -(pi / 4) + [InlineData(-0.707106781f, -0.387452673f, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, -0.381496862f, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.636619772f, -0.356781758f, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.434294482f, -0.259944426f, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.318309886f, -0.197991121f, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0f, 0.0f, 0.0f)] + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData( 0.0f, 0.0f, 0.0f)] + [InlineData( 0.318309886f, 0.246868989f, CrossPlatformMachineEpsilon)] // value: (1 / pi) + [InlineData( 0.434294482f, 0.351249873f, CrossPlatformMachineEpsilon)] // value: (log10(e)) + [InlineData( 0.636619772f, 0.554682275f, CrossPlatformMachineEpsilon)] // value: (2 / pi) + [InlineData( 0.693147181f, 0.616806672f, CrossPlatformMachineEpsilon)] // value: (ln(2)) + [InlineData( 0.707106781f, 0.632526919f, CrossPlatformMachineEpsilon)] // value: (1 / sqrt(2)) + [InlineData( 0.785398163f, 0.723567934f, CrossPlatformMachineEpsilon)] // value: (pi / 4) + [InlineData( 1.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.12837917f, 1.18612996f, CrossPlatformMachineEpsilon * 10)] // value: (2 / sqrt(pi)) + [InlineData( 1.41421356f, 1.66514414f, CrossPlatformMachineEpsilon * 10)] // value: (sqrt(2)) + [InlineData( 1.44269504f, 1.71828183f, CrossPlatformMachineEpsilon * 10)] // value: (log2(e)) + [InlineData( 1.57079633f, 1.97068642f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 2) + [InlineData( 2.30258509f, 3.93340967f, CrossPlatformMachineEpsilon * 10)] // value: (ln(10)) + [InlineData( 2.71828183f, 5.58088599f, CrossPlatformMachineEpsilon * 10)] // value: (e) + [InlineData( 3.14159265f, 7.82497783f, CrossPlatformMachineEpsilon * 10)] // value: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Exp2M1Test(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, float.Exp2M1(value), allowedVariance); + } + + [Theory] + [InlineData( float.NegativeInfinity, 0.0f, 0.0f)] + [InlineData(-3.14159265f, 0.000721784159f, CrossPlatformMachineEpsilon / 1000)] // value: -(pi) + [InlineData(-2.71828183f, 0.00191301410f, CrossPlatformMachineEpsilon / 100)] // value: -(e) + [InlineData(-2.30258509f, 0.00498212830f, CrossPlatformMachineEpsilon / 100)] // value: -(ln(10)) + [InlineData(-1.57079633f, 0.0268660410f, CrossPlatformMachineEpsilon / 10)] // value: -(pi / 2) + [InlineData(-1.44269504f, 0.0360831928f, CrossPlatformMachineEpsilon / 10)] // value: -(log2(e)) + [InlineData(-1.41421356f, 0.0385288847f, CrossPlatformMachineEpsilon / 10)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, 0.0744082059f, CrossPlatformMachineEpsilon / 10)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, 0.1f, CrossPlatformMachineEpsilon)] + [InlineData(-0.785398163f, 0.163908636f, CrossPlatformMachineEpsilon)] // value: -(pi / 4) + [InlineData(-0.707106781f, 0.196287760f, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, 0.202699566f, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.636619772f, 0.230876765f, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.434294482f, 0.367879441f, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.318309886f, 0.480496373f, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0f, 1.0f, 0.0f)] + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData( 0.0f, 1.0f, 0.0f)] + [InlineData( 0.318309886f, 2.08118116f, CrossPlatformMachineEpsilon * 10)] // value: (1 / pi) + [InlineData( 0.434294482f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // value: (log10(e)) + [InlineData( 0.636619772f, 4.33131503f, CrossPlatformMachineEpsilon * 10)] // value: (2 / pi) + [InlineData( 0.693147181f, 4.93340967f, CrossPlatformMachineEpsilon * 10)] // value: (ln(2)) + [InlineData( 0.707106781f, 5.09456117f, CrossPlatformMachineEpsilon * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.785398163f, 6.10095980f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 4) + [InlineData( 1.0f, 10.0f, CrossPlatformMachineEpsilon * 100)] + [InlineData( 1.12837917f, 13.4393779f, CrossPlatformMachineEpsilon * 100)] // value: (2 / sqrt(pi)) + [InlineData( 1.41421356f, 25.9545535f, CrossPlatformMachineEpsilon * 100)] // value: (sqrt(2)) + [InlineData( 1.44269504f, 27.7137338f, CrossPlatformMachineEpsilon * 100)] // value: (log2(e)) + [InlineData( 1.57079633f, 37.2217105f, CrossPlatformMachineEpsilon * 100)] // value: (pi / 2) + [InlineData( 2.30258509f, 200.717432f, CrossPlatformMachineEpsilon * 1000)] // value: (ln(10)) + [InlineData( 2.71828183f, 522.735300f, CrossPlatformMachineEpsilon * 1000)] // value: (e) + [InlineData( 3.14159265f, 1385.45573f, CrossPlatformMachineEpsilon * 10000)] // value: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Exp10Test(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, float.Exp10(value), allowedVariance); + } + + [Theory] + [InlineData( float.NegativeInfinity, -1.0f, 0.0f)] + [InlineData(-3.14159265f, -0.999278216f, CrossPlatformMachineEpsilon)] // value: -(pi) + [InlineData(-2.71828183f, -0.998086986f, CrossPlatformMachineEpsilon)] // value: -(e) + [InlineData(-2.30258509f, -0.995017872f, CrossPlatformMachineEpsilon)] // value: -(ln(10)) + [InlineData(-1.57079633f, -0.973133959f, CrossPlatformMachineEpsilon)] // value: -(pi / 2) + [InlineData(-1.44269504f, -0.963916807f, CrossPlatformMachineEpsilon)] // value: -(log2(e)) + [InlineData(-1.41421356f, -0.961471115f, CrossPlatformMachineEpsilon)] // value: -(sqrt(2)) + [InlineData(-1.12837917f, -0.925591794f, CrossPlatformMachineEpsilon)] // value: -(2 / sqrt(pi)) + [InlineData(-1.0f, -0.9f, CrossPlatformMachineEpsilon)] + [InlineData(-0.785398163f, -0.836091364f, CrossPlatformMachineEpsilon)] // value: -(pi / 4) + [InlineData(-0.707106781f, -0.803712240f, CrossPlatformMachineEpsilon)] // value: -(1 / sqrt(2)) + [InlineData(-0.693147181f, -0.797300434f, CrossPlatformMachineEpsilon)] // value: -(ln(2)) + [InlineData(-0.636619772f, -0.769123235f, CrossPlatformMachineEpsilon)] // value: -(2 / pi) + [InlineData(-0.434294482f, -0.632120559f, CrossPlatformMachineEpsilon)] // value: -(log10(e)) + [InlineData(-0.318309886f, -0.519503627f, CrossPlatformMachineEpsilon)] // value: -(1 / pi) + [InlineData(-0.0f, 0.0f, 0.0f)] + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData( 0.0f, 0.0f, 0.0f)] + [InlineData( 0.318309886f, 1.08118116f, CrossPlatformMachineEpsilon * 10)] // value: (1 / pi) + [InlineData( 0.434294482f, 1.71828183f, CrossPlatformMachineEpsilon * 10)] // value: (log10(e)) + [InlineData( 0.636619772f, 3.33131503f, CrossPlatformMachineEpsilon * 10)] // value: (2 / pi) + [InlineData( 0.693147181f, 3.93340967f, CrossPlatformMachineEpsilon * 10)] // value: (ln(2)) + [InlineData( 0.707106781f, 4.09456117f, CrossPlatformMachineEpsilon * 10)] // value: (1 / sqrt(2)) + [InlineData( 0.785398163f, 5.10095980f, CrossPlatformMachineEpsilon * 10)] // value: (pi / 4) + [InlineData( 1.0f, 9.0, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.12837917f, 12.4393779f, CrossPlatformMachineEpsilon * 100)] // value: (2 / sqrt(pi)) + [InlineData( 1.41421356f, 24.9545535f, CrossPlatformMachineEpsilon * 100)] // value: (sqrt(2)) + [InlineData( 1.44269504f, 26.7137338f, CrossPlatformMachineEpsilon * 100)] // value: (log2(e)) + [InlineData( 1.57079633f, 36.2217105f, CrossPlatformMachineEpsilon * 100)] // value: (pi / 2) + [InlineData( 2.30258509f, 199.717432f, CrossPlatformMachineEpsilon * 1000)] // value: (ln(10)) + [InlineData( 2.71828183f, 521.735300f, CrossPlatformMachineEpsilon * 1000)] // value: (e) + [InlineData( 3.14159265f, 1384.45573f, CrossPlatformMachineEpsilon * 10000)] // value: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Exp10M1Test(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, float.Exp10M1(value), allowedVariance); + } + + [Theory] + [InlineData( float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(-3.14159265f, float.NaN, 0.0f)] // value: -(pi) + [InlineData(-2.71828183f, float.NaN, 0.0f)] // value: -(e) + [InlineData(-1.41421356f, float.NaN, 0.0f)] // value: -(sqrt(2)) + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData(-1.0f, float.NegativeInfinity, 0.0f)] + [InlineData(-0.956786082f, -3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi) + [InlineData(-0.934011964f, -2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: -(e) + [InlineData(-0.9f, -2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: -(ln(10)) + [InlineData(-0.792120424f, -1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(-0.763709912f, -1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: -(log2(e)) + [InlineData(-0.756883266f, -1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: -(sqrt(2)) + [InlineData(-0.676442736f, -1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(-0.632120559f, -1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.544061872f, -0.785398163f, CrossPlatformMachineEpsilon)] // expected: -(pi / 4) + [InlineData(-0.506931309f, -0.707106781f, CrossPlatformMachineEpsilon)] // expected: -(1 / sqrt(2)) + [InlineData(-0.5f, -0.693147181f, CrossPlatformMachineEpsilon)] // expected: -(ln(2)) + [InlineData(-0.470922192f, -0.636619772f, CrossPlatformMachineEpsilon)] // expected: -(2 / pi) + [InlineData(-0.0f, 0.0f, 0.0f)] + [InlineData( 0.0f, 0.0f, 0.0f)] + [InlineData( 0.374802227f, 0.318309886f, CrossPlatformMachineEpsilon)] // expected: (1 / pi) + [InlineData( 0.543873444f, 0.434294482f, CrossPlatformMachineEpsilon)] // expected: (log10(e)) + [InlineData( 0.890081165f, 0.636619772f, CrossPlatformMachineEpsilon)] // expected: (2 / pi) + [InlineData( 1.0f, 0.693147181f, CrossPlatformMachineEpsilon)] // expected: (ln(2)) + [InlineData( 1.02811498f, 0.707106781f, CrossPlatformMachineEpsilon)] // expected: (1 / sqrt(2)) + [InlineData( 1.19328005f, 0.785398163f, CrossPlatformMachineEpsilon)] // expected: (pi / 4) + [InlineData( 1.71828183f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 2.09064302f, 1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: (2 / sqrt(pi)) + [InlineData( 3.11325038f, 1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: (sqrt(2)) + [InlineData( 3.23208611f, 1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: (log2(e)) + [InlineData( 3.81047738f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData( 9.0f, 2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: (ln(10)) + [InlineData( 14.1542622f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: (e) + [InlineData( 22.1406926f, 3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void LogP1Test(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, float.LogP1(value), allowedVariance); + } + + [Theory] + [InlineData( float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData(-1.0f, float.NegativeInfinity, 0.0f)] + [InlineData(-0.886685268f, -3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi) + [InlineData(-0.848044777f, -2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: -(e) + [InlineData(-0.797300434f, -2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: -(ln(10)) + [InlineData(-0.663377463f, -1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(-0.632120559f, -1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: -(log2(e)) + [InlineData(-0.624785773f, -1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: -(sqrt(2)) + [InlineData(-0.542570653f, -1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(-0.5f, -1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.419808190f, -0.785398163f, CrossPlatformMachineEpsilon)] // expected: -(pi / 4) + [InlineData(-0.387452673f, -0.707106781f, CrossPlatformMachineEpsilon)] // expected: -(1 / sqrt(2)) + [InlineData(-0.381496862f, -0.693147181f, CrossPlatformMachineEpsilon)] // expected: -(ln(2)) + [InlineData(-0.356781758f, -0.636619772f, CrossPlatformMachineEpsilon)] // expected: -(2 / pi) + [InlineData(-0.259944426f, -0.434294482f, CrossPlatformMachineEpsilon)] // expected: -(log10(e)) + [InlineData(-0.197991121f, -0.318309886f, CrossPlatformMachineEpsilon)] // expected: -(1 / pi) + [InlineData(-0.0f, 0.0f, 0.0f)] + [InlineData( 0.0f, 0.0f, 0.0f)] + [InlineData( 0.246868989f, 0.318309886f, CrossPlatformMachineEpsilon)] // expected: (1 / pi) + [InlineData( 0.351249873f, 0.434294482f, CrossPlatformMachineEpsilon)] // expected: (log10(e)) + [InlineData( 0.554682275f, 0.636619772f, CrossPlatformMachineEpsilon)] // expected: (2 / pi) + [InlineData( 0.616806672f, 0.693147181f, CrossPlatformMachineEpsilon)] // expected: (ln(2)) + [InlineData( 0.632526919f, 0.707106781f, CrossPlatformMachineEpsilon)] // expected: (1 / sqrt(2)) + [InlineData( 0.723567934f, 0.785398163f, CrossPlatformMachineEpsilon)] // expected: (pi / 4) + [InlineData( 1.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 1.18612996f, 1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: (2 / sqrt(pi)) + [InlineData( 1.66514414f, 1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: (sqrt(2)) + [InlineData( 1.71828183f, 1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: (log2(e)) + [InlineData( 1.97068642f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData( 3.93340967f, 2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: (ln(10)) + [InlineData( 5.58088599f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: (e) + [InlineData( 7.82497783f, 3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Log2P1Test(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, float.Log2P1(value), allowedVariance); + } + + [Theory] + [InlineData( float.NegativeInfinity, float.NaN, 0.0f)] + [InlineData(-3.14159265f, float.NaN, 0.0f)] // value: -(pi) + [InlineData(-2.71828183f, float.NaN, 0.0f)] // value: -(e) + [InlineData(-1.41421356f, float.NaN, 0.0f)] // value: -(sqrt(2)) + [InlineData( float.NaN, float.NaN, 0.0f)] + [InlineData(-1.0f, float.NegativeInfinity, 0.0f)] + [InlineData(-0.998086986f, -2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: -(e) + [InlineData(-0.995017872f, -2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: -(ln(10)) + [InlineData(-0.973133959f, -1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: -(pi / 2) + [InlineData(-0.963916807f, -1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: -(log2(e)) + [InlineData(-0.961471115f, -1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: -(sqrt(2)) + [InlineData(-0.925591794f, -1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: -(2 / sqrt(pi)) + [InlineData(-0.9f, -1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData(-0.836091364f, -0.785398163f, CrossPlatformMachineEpsilon)] // expected: -(pi / 4) + [InlineData(-0.803712240f, -0.707106781f, CrossPlatformMachineEpsilon)] // expected: -(1 / sqrt(2)) + [InlineData(-0.797300434f, -0.693147181f, CrossPlatformMachineEpsilon)] // expected: -(ln(2)) + [InlineData(-0.769123235f, -0.636619772f, CrossPlatformMachineEpsilon)] // expected: -(2 / pi) + [InlineData(-0.632120559f, -0.434294482f, CrossPlatformMachineEpsilon)] // expected: -(log10(e)) + [InlineData(-0.519503627f, -0.318309886f, CrossPlatformMachineEpsilon)] // expected: -(1 / pi) + [InlineData(-0.0f, 0.0f, 0.0f)] + [InlineData( 0.0f, 0.0f, 0.0f)] + [InlineData( 1.08118116f, 0.318309886f, CrossPlatformMachineEpsilon)] // expected: (1 / pi) + [InlineData( 1.71828183f, 0.434294482f, CrossPlatformMachineEpsilon)] // expected: (log10(e)) value: (e) + [InlineData( 3.33131503f, 0.636619772f, CrossPlatformMachineEpsilon)] // expected: (2 / pi) + [InlineData( 3.93340967f, 0.693147181f, CrossPlatformMachineEpsilon)] // expected: (ln(2)) + [InlineData( 4.09456117f, 0.707106781f, CrossPlatformMachineEpsilon)] // expected: (1 / sqrt(2)) + [InlineData( 5.10095980f, 0.785398163f, CrossPlatformMachineEpsilon)] // expected: (pi / 4) + [InlineData( 9.0f, 1.0f, CrossPlatformMachineEpsilon * 10)] + [InlineData( 12.4393779f, 1.12837917f, CrossPlatformMachineEpsilon * 10)] // expected: (2 / sqrt(pi)) + [InlineData( 24.9545535f, 1.41421356f, CrossPlatformMachineEpsilon * 10)] // expected: (sqrt(2)) + [InlineData( 26.7137338f, 1.44269504f, CrossPlatformMachineEpsilon * 10)] // expected: (log2(e)) + [InlineData( 36.2217105f, 1.57079633f, CrossPlatformMachineEpsilon * 10)] // expected: (pi / 2) + [InlineData( 199.717432f, 2.30258509f, CrossPlatformMachineEpsilon * 10)] // expected: (ln(10)) + [InlineData( 521.735300f, 2.71828183f, CrossPlatformMachineEpsilon * 10)] // expected: (e) + [InlineData( 1384.45573f, 3.14159265f, CrossPlatformMachineEpsilon * 10)] // expected: (pi) + [InlineData( float.PositiveInfinity, float.PositiveInfinity, 0.0f)] + public static void Log10P1Test(float value, float expectedResult, float allowedVariance) + { + AssertExtensions.Equal(expectedResult, float.Log10P1(value), allowedVariance); + } } }