Add comprehensive math tests

Introduces extension methods for decimal
This commit is contained in:
Oliver Booth 2022-04-30 10:15:36 +01:00
parent 8d4f82e964
commit 2547d4a227
No known key found for this signature in database
GPG Key ID: 32A00B35503AF634
10 changed files with 835 additions and 239 deletions

View File

@ -1,108 +0,0 @@
using System.Diagnostics;
using System.Numerics;
using X10D.Math;
using X10D.Numerics;
namespace X10D.Tests.Core;
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
/// <summary>
/// Tests for <see cref="DoubleExtensions" />.
/// </summary>
[TestClass]
public class DoubleTests
{
[TestMethod]
public void ComplexSqrt()
{
Assert.AreEqual(0.0, 0.0.ComplexSqrt());
Assert.AreEqual(1.414213562373095, 2.0.ComplexSqrt());
Assert.AreEqual(3.0, 9.0.ComplexSqrt());
Assert.AreEqual(4.0, 16.0.ComplexSqrt());
Assert.AreEqual(new Complex(1.414213562373095, 1), (-2.0).ComplexSqrt());
Assert.AreEqual(new Complex(3.0, 1), (-9.0).ComplexSqrt());
Assert.AreEqual(new Complex(4.0, 1), (-16.0).ComplexSqrt());
Assert.AreEqual(Complex.NaN, double.NaN.ComplexSqrt());
Assert.AreEqual(new Complex(1, 1), (-1.0).ComplexSqrt());
Assert.AreEqual(Complex.Infinity, double.NegativeInfinity.ComplexSqrt());
Assert.AreEqual(Complex.Infinity, double.PositiveInfinity.ComplexSqrt());
}
/// <summary>
/// Tests for <see cref="DoubleExtensions.DegreesToRadians" />.
/// </summary>
[TestMethod]
public void DegreesToRadians()
{
Assert.AreEqual(Math.PI, 180.0.DegreesToRadians());
Assert.AreEqual(Math.PI * 1.5, 270.0.DegreesToRadians());
Assert.AreEqual(0.0, 0.0.DegreesToRadians());
Assert.AreEqual(0.017453292519943295, 1.0.DegreesToRadians());
Assert.AreEqual(0.10471975511965978, 6.0.DegreesToRadians());
Assert.AreEqual(0.20943951023931956, 12.0.DegreesToRadians());
}
/// <summary>
/// Tests for <see cref="DoubleExtensions.IsEven" />.
/// </summary>
[TestMethod]
public void IsEven()
{
Assert.IsTrue(2.0.IsEven());
Assert.IsFalse(1.0.IsEven());
}
/// <summary>
/// Tests for <see cref="DoubleExtensions.IsOdd" />.
/// </summary>
[TestMethod]
public void IsOdd()
{
Assert.IsFalse(2.0.IsOdd());
Assert.IsTrue(1.0.IsOdd());
}
/// <summary>
/// Tests for <see cref="DoubleExtensions.RadiansToDegrees" />.
/// </summary>
[TestMethod]
public void RadiansToDegrees()
{
Assert.AreEqual(180.0, Math.PI.RadiansToDegrees());
Assert.AreEqual(360.0, (2.0 * Math.PI).RadiansToDegrees());
Assert.AreEqual(0.0, 0.0.RadiansToDegrees());
Assert.AreEqual(1.0, 0.017453292519943295.RadiansToDegrees());
Assert.AreEqual(6.000000000000001, 0.10471975511965978.RadiansToDegrees()); // rounding errors are fun
Assert.AreEqual(12.0, 0.20943951023931953.RadiansToDegrees());
}
/// <summary>
/// Tests for <see cref="DoubleExtensions.Round(double)" /> and <see cref="DoubleExtensions.Round(double, double)" />.
/// </summary>
[TestMethod]
public void Round()
{
Assert.AreEqual(4.0, 3.5.Round());
Assert.AreEqual(7.0, 6.8.Round());
Assert.AreEqual(7.0, 7.2.Round());
Assert.AreEqual(5.0, 3.5.Round(5));
Assert.AreEqual(5.0, 7.0.Round(5));
Assert.AreEqual(10.0, 7.5.Round(5));
}
[TestMethod]
public void Sqrt()
{
Assert.AreEqual(0.0, 0.0.Sqrt());
Assert.AreEqual(1.414213562373095, 2.0.Sqrt());
Assert.AreEqual(3.0, 9.0.Sqrt());
Assert.AreEqual(4.0, 16.0.Sqrt());
Assert.AreEqual(double.NaN, double.NaN.Sqrt());
Assert.AreEqual(double.NaN, (-1.0).Sqrt());
Assert.AreEqual(double.NaN, double.NegativeInfinity.Sqrt());
Assert.AreEqual(double.PositiveInfinity, double.PositiveInfinity.Sqrt());
}
}

View File

@ -1,61 +0,0 @@
using System.Numerics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using X10D.Math;
using X10D.Numerics;
namespace X10D.Tests.Core;
[TestClass]
public class SingleTests
{
[TestMethod]
public void ComplexSqrt()
{
Assert.AreEqual(0.0f, 0.0f.ComplexSqrt());
Assert.AreEqual(1.4142135f, 2.0f.ComplexSqrt());
Assert.AreEqual(3.0f, 9.0f.ComplexSqrt());
Assert.AreEqual(4.0f, 16.0f.ComplexSqrt());
Assert.AreEqual(new Complex(1.4142135f, 1), (-2.0f).ComplexSqrt());
Assert.AreEqual(new Complex(3.0f, 1), (-9.0f).ComplexSqrt());
Assert.AreEqual(new Complex(4.0f, 1), (-16.0f).ComplexSqrt());
Assert.AreEqual(Complex.NaN, float.NaN.ComplexSqrt());
Assert.AreEqual(new Complex(1, 1), (-1.0f).ComplexSqrt());
Assert.AreEqual(Complex.Infinity, float.NegativeInfinity.ComplexSqrt());
Assert.AreEqual(Complex.Infinity, float.PositiveInfinity.ComplexSqrt());
}
[TestMethod]
public void DegreesToRadians()
{
Assert.AreEqual(MathF.PI, 180.0f.DegreesToRadians());
Assert.AreEqual(MathF.PI * 1.5f, 270.0f.DegreesToRadians());
Assert.AreEqual(0.0f, 0.0f.DegreesToRadians());
Assert.AreEqual(0.017453292f, 1.0f.DegreesToRadians());
Assert.AreEqual(0.10471976f, 6.0f.DegreesToRadians());
Assert.AreEqual(0.20943952f, 12.0f.DegreesToRadians());
}
[TestMethod]
public void RadiansToDegrees()
{
Assert.AreEqual(180.0f, MathF.PI.RadiansToDegrees());
Assert.AreEqual(270.0f, (MathF.PI * 1.5f).RadiansToDegrees());
Assert.AreEqual(0.0, 0.0f.RadiansToDegrees());
Assert.AreEqual(0.99999994f, 0.017453292f.RadiansToDegrees()); // rounding errors are fun
Assert.AreEqual(6.0f, 0.10471976f.RadiansToDegrees());
Assert.AreEqual(12.0f, 0.20943952f.RadiansToDegrees());
}
[TestMethod]
public void Sqrt()
{
Assert.AreEqual(0.0f, 0.0f.Sqrt());
Assert.AreEqual(1.4142135f, 2.0f.Sqrt());
Assert.AreEqual(3.0f, 9.0f.Sqrt());
Assert.AreEqual(4.0f, 16.0f.Sqrt());
Assert.AreEqual(float.NaN, float.NaN.Sqrt());
Assert.AreEqual(float.NaN, (-1.0f).Sqrt());
Assert.AreEqual(float.NaN, float.NegativeInfinity.Sqrt());
Assert.AreEqual(float.PositiveInfinity, float.PositiveInfinity.Sqrt());
}
}

View File

@ -0,0 +1,122 @@
using System.Numerics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using X10D.Math;
namespace X10D.Tests.Math;
[TestClass]
public class DecimalTests
{
[TestMethod]
public void ComplexSqrt_ShouldBeCorrect_GivenReal()
{
Assert.AreEqual(0.0, 0.0m.ComplexSqrt());
Assert.AreEqual(1.4142135623730951, 2.0m.ComplexSqrt());
Assert.AreEqual(3.0, 9.0m.ComplexSqrt());
Assert.AreEqual(4.0, 16.0m.ComplexSqrt());
Assert.AreEqual(100.0, 10000.0m.ComplexSqrt());
}
[TestMethod]
public void ComplexSqrt_ShouldBeImaginary_GivenNegativeValue()
{
Assert.AreEqual(new Complex(0, 1), (-1.0m).ComplexSqrt());
Assert.AreEqual(new Complex(0, 1.4142135623730951), (-2.0m).ComplexSqrt());
Assert.AreEqual(new Complex(0, 3.0), (-9.0m).ComplexSqrt());
Assert.AreEqual(new Complex(0, 4.0), (-16.0m).ComplexSqrt());
}
[TestMethod]
public void IsEven_ShouldBeFalse_GivenOddNumber()
{
Assert.IsFalse((-3.0m).IsEven());
Assert.IsFalse((-1.0m).IsEven());
Assert.IsFalse(1.0m.IsEven());
Assert.IsFalse(3.0m.IsEven());
}
[TestMethod]
public void IsEven_ShouldBeTrue_GivenOddNumber()
{
Assert.IsTrue((-4.0m).IsEven());
Assert.IsTrue((-2.0m).IsEven());
Assert.IsTrue(0.0m.IsEven());
Assert.IsTrue(2.0m.IsEven());
Assert.IsTrue(4.0m.IsEven());
}
[TestMethod]
public void IsOdd_ShouldBeFalse_GivenEvenNumber()
{
Assert.IsFalse((-4.0m).IsOdd());
Assert.IsFalse((-2.0m).IsOdd());
Assert.IsFalse(0.0m.IsOdd());
Assert.IsFalse(2.0m.IsOdd());
Assert.IsFalse(4.0m.IsOdd());
}
[TestMethod]
public void IsOdd_ShouldBeTrue_GivenOddNumber()
{
Assert.IsTrue((-3.0m).IsOdd());
Assert.IsTrue((-1.0m).IsOdd());
Assert.IsTrue(1.0m.IsOdd());
Assert.IsTrue(3.0m.IsOdd());
}
[TestMethod]
public void Round_ShouldRoundToNearestInteger()
{
Assert.AreEqual(4.0m, 3.5m.Round());
Assert.AreEqual(7.0m, 6.8m.Round());
Assert.AreEqual(7.0m, 7.2m.Round());
}
[TestMethod]
public void Round_ShouldRoundToNearestMultiple()
{
Assert.AreEqual(5.0m, 3.5m.Round(5));
Assert.AreEqual(5.0m, 7.0m.Round(5));
Assert.AreEqual(10.0m, 7.5m.Round(5));
}
[TestMethod]
public void Sign_ShouldBeMinus1_GivenNegative()
{
Assert.AreEqual(-1, -1.0m.Sign());
Assert.AreEqual(-1, -2.0m.Sign());
Assert.AreEqual(-1, -3.0m.Sign());
}
[TestMethod]
public void Sign_ShouldBe0_Given0()
{
Assert.AreEqual(0, 0.0m.Sign());
}
[TestMethod]
public void Sign_ShouldBe1_GivenPositive()
{
Assert.AreEqual(1, 1.0m.Sign());
Assert.AreEqual(1, 2.0m.Sign());
Assert.AreEqual(1, 3.0m.Sign());
}
[TestMethod]
public void Sqrt_ShouldBeCorrect_GivenValue()
{
Assert.AreEqual(0.0m, 0.0m.Sqrt());
Assert.AreEqual(1.4142135623730950488016887242m, 2.0m.Sqrt());
Assert.AreEqual(3.0m, 9.0m.Sqrt());
Assert.AreEqual(4.0m, 16.0m.Sqrt());
Assert.AreEqual(100.0m, 10000.0m.Sqrt());
}
[TestMethod]
public void Sqrt_ShouldThrow_GivenNegativeValue()
{
Assert.ThrowsException<ArgumentException>(() => (-1.0m).Sqrt());
Assert.ThrowsException<ArgumentException>(() => (-2.0m).Sqrt());
Assert.ThrowsException<ArgumentException>(() => (-3.0m).Sqrt());
}
}

View File

@ -0,0 +1,242 @@
using System.Numerics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using X10D.Math;
namespace X10D.Tests.Math;
[TestClass]
public class DoubleTests
{
[TestMethod]
public void DegreesToRadians_ShouldBeCorrect()
{
Assert.AreEqual(System.Math.PI, 180.0.DegreesToRadians());
Assert.AreEqual(System.Math.PI * 1.5, 270.0.DegreesToRadians());
Assert.AreEqual(0.0, 0.0.DegreesToRadians());
Assert.AreEqual(0.017453292519943295, 1.0.DegreesToRadians());
Assert.AreEqual(0.10471975511965978, 6.0.DegreesToRadians());
Assert.AreEqual(0.20943951023931956, 12.0.DegreesToRadians());
}
[TestMethod]
public void RadiansToDegrees_ShouldBeCorrect()
{
Assert.AreEqual(180.0, System.Math.PI.RadiansToDegrees());
Assert.AreEqual(360.0, (2.0 * System.Math.PI).RadiansToDegrees());
Assert.AreEqual(0.0, 0.0.RadiansToDegrees());
Assert.AreEqual(1.0, 0.017453292519943295.RadiansToDegrees());
Assert.AreEqual(6.000000000000001, 0.10471975511965978.RadiansToDegrees()); // rounding errors are fun
Assert.AreEqual(12.0, 0.20943951023931953.RadiansToDegrees());
}
[TestMethod]
public void ComplexSqrt_ShouldBeCorrect_GivenReal()
{
Assert.AreEqual(0.0, 0.0.ComplexSqrt());
Assert.AreEqual(1.4142135623730951, 2.0.ComplexSqrt());
Assert.AreEqual(3.0, 9.0.ComplexSqrt());
Assert.AreEqual(4.0, 16.0.ComplexSqrt());
Assert.AreEqual(100.0, 10000.0.ComplexSqrt());
}
[TestMethod]
public void ComplexSqrt_ShouldBeImaginary_GivenNegativeValue()
{
Assert.AreEqual(new Complex(0, 1), (-1.0).ComplexSqrt());
Assert.AreEqual(new Complex(0, 1.4142135623730951), (-2.0).ComplexSqrt());
Assert.AreEqual(new Complex(0, 3.0), (-9.0).ComplexSqrt());
Assert.AreEqual(new Complex(0, 4.0), (-16.0).ComplexSqrt());
}
[TestMethod]
public void ComplexSqrt_ShouldBeComplexInfinity_GivenInfinity()
{
Assert.AreEqual(Complex.Infinity, double.NegativeInfinity.ComplexSqrt());
Assert.AreEqual(Complex.Infinity, double.PositiveInfinity.ComplexSqrt());
}
[TestMethod]
public void ComplexSqrt_ShouldBeNaN_GivenNaN()
{
Assert.AreEqual(Complex.NaN, double.NaN.ComplexSqrt());
}
[TestMethod]
public void IsEven_ShouldBeFalse_GivenOddNumber()
{
Assert.IsFalse((-3.0).IsEven());
Assert.IsFalse((-1.0).IsEven());
Assert.IsFalse(1.0.IsEven());
Assert.IsFalse(3.0.IsEven());
}
[TestMethod]
public void IsEven_ShouldBeTrue_GivenOddNumber()
{
Assert.IsTrue((-4.0).IsEven());
Assert.IsTrue((-2.0).IsEven());
Assert.IsTrue(0.0.IsEven());
Assert.IsTrue(2.0.IsEven());
Assert.IsTrue(4.0.IsEven());
}
[TestMethod]
public void IsOdd_ShouldBeFalse_GivenEvenNumber()
{
Assert.IsFalse((-4.0).IsOdd());
Assert.IsFalse((-2.0).IsOdd());
Assert.IsFalse(0.0.IsOdd());
Assert.IsFalse(2.0.IsOdd());
Assert.IsFalse(4.0.IsOdd());
}
[TestMethod]
public void IsOdd_ShouldBeTrue_GivenOddNumber()
{
Assert.IsTrue((-3.0).IsOdd());
Assert.IsTrue((-1.0).IsOdd());
Assert.IsTrue(1.0.IsOdd());
Assert.IsTrue(3.0.IsOdd());
}
[TestMethod]
public void Round_ShouldRoundToNearestInteger()
{
Assert.AreEqual(4.0, 3.5.Round());
Assert.AreEqual(7.0, 6.8.Round());
Assert.AreEqual(7.0, 7.2.Round());
}
[TestMethod]
public void Round_ShouldRoundToNearestMultiple()
{
Assert.AreEqual(5.0, 3.5.Round(5));
Assert.AreEqual(5.0, 7.0.Round(5));
Assert.AreEqual(10.0, 7.5.Round(5));
}
[TestMethod]
public void Sign_ShouldBeMinus1_GivenNegative()
{
Assert.AreEqual(-1, -1.0.Sign());
Assert.AreEqual(-1, -2.0.Sign());
Assert.AreEqual(-1, -3.0.Sign());
}
[TestMethod]
public void Sign_ShouldBe0_Given0()
{
Assert.AreEqual(0, 0.0.Sign());
}
[TestMethod]
public void Sign_ShouldBe1_GivenPositive()
{
Assert.AreEqual(1, 1.0.Sign());
Assert.AreEqual(1, 2.0.Sign());
Assert.AreEqual(1, 3.0.Sign());
}
[TestMethod]
public void Sqrt_ShouldBeCorrect_GivenValue()
{
Assert.AreEqual(0.0, 0.0.Sqrt());
Assert.AreEqual(1.414213562373095, 2.0.Sqrt());
Assert.AreEqual(3.0, 9.0.Sqrt());
Assert.AreEqual(4.0, 16.0.Sqrt());
Assert.AreEqual(100.0, 10000.0.Sqrt());
}
[TestMethod]
public void Sqrt_ShouldBeNaN_GivenNaN()
{
Assert.AreEqual(double.NaN, double.NaN.Sqrt());
}
[TestMethod]
public void Sqrt_ShouldBeNaN_GivenNegativeValue()
{
Assert.AreEqual(double.NaN, (-1.0).Sqrt());
Assert.AreEqual(double.NaN, (-2.0).Sqrt());
Assert.AreEqual(double.NaN, (-3.0).Sqrt());
Assert.AreEqual(double.NaN, double.NegativeInfinity.Sqrt());
}
[TestMethod]
public void Sqrt_ShouldBePositiveInfinity_GivenPositiveInfinity()
{
Assert.AreEqual(double.PositiveInfinity, double.PositiveInfinity.Sqrt());
}
[TestMethod]
public void Acos_ShouldBeCorrect()
{
Assert.AreEqual(1.0471975511965979, 0.5.Acos());
}
[TestMethod]
public void Acosh_ShouldBeCorrect()
{
Assert.AreEqual(0.9624236501192069, 1.5.Acosh());
}
[TestMethod]
public void Asin_ShouldBeCorrect()
{
Assert.AreEqual(0.5235987755982989, 0.5.Asin());
}
[TestMethod]
public void Asinh_ShouldBeCorrect()
{
Assert.AreEqual(1.1947632172871094, 1.5.Asinh());
}
[TestMethod]
public void Atan_ShouldBeCorrect()
{
Assert.AreEqual(0.4636476090008061, 0.5.Atan());
}
[TestMethod]
public void Atanh_ShouldBeCorrect()
{
Assert.AreEqual(0.5493061443340549, 0.5.Atanh());
}
[TestMethod]
public void Cos_ShouldBeCorrect()
{
Assert.AreEqual(0.8775825618903728, 0.5.Cos());
}
[TestMethod]
public void Cosh_ShouldBeCorrect()
{
Assert.AreEqual(2.352409615243247, 1.5.Cosh());
}
[TestMethod]
public void Sin_ShouldBeCorrect()
{
Assert.AreEqual(0.479425538604203, 0.5.Sin());
}
[TestMethod]
public void Sinh_ShouldBeCorrect()
{
Assert.AreEqual(2.1292794550948173, 1.5.Sinh());
}
[TestMethod]
public void Tan_ShouldBeCorrect()
{
Assert.AreEqual(0.5463024898437905, 0.5.Tan());
}
[TestMethod]
public void Tanh_ShouldBeCorrect()
{
Assert.AreEqual(0.46211715726000974, 0.5.Tanh());
}
}

View File

@ -0,0 +1,242 @@
using System.Numerics;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using X10D.Math;
namespace X10D.Tests.Math;
[TestClass]
public class SingleTests
{
[TestMethod]
public void DegreesToRadians_ShouldBeCorrect()
{
Assert.AreEqual(MathF.PI, 180.0f.DegreesToRadians());
Assert.AreEqual(MathF.PI * 1.5f, 270.0f.DegreesToRadians());
Assert.AreEqual(0.0f, 0.0f.DegreesToRadians());
Assert.AreEqual(0.017453292f, 1.0f.DegreesToRadians());
Assert.AreEqual(0.10471976f, 6.0f.DegreesToRadians());
Assert.AreEqual(0.20943952f, 12.0f.DegreesToRadians());
}
[TestMethod]
public void RadiansToDegrees_ShouldBeCorrect()
{
Assert.AreEqual(180.0f, MathF.PI.RadiansToDegrees());
Assert.AreEqual(270.0f, (MathF.PI * 1.5f).RadiansToDegrees());
Assert.AreEqual(0.0, 0.0f.RadiansToDegrees());
Assert.AreEqual(0.99999994f, 0.017453292f.RadiansToDegrees()); // rounding errors are fun
Assert.AreEqual(6.0f, 0.10471976f.RadiansToDegrees());
Assert.AreEqual(12.0f, 0.20943952f.RadiansToDegrees());
}
[TestMethod]
public void ComplexSqrt_ShouldBeCorrect_GivenReal()
{
Assert.AreEqual(0.0f, 0.0f.ComplexSqrt());
Assert.AreEqual(1.4142135f, 2.0f.ComplexSqrt());
Assert.AreEqual(3.0f, 9.0f.ComplexSqrt());
Assert.AreEqual(4.0f, 16.0f.ComplexSqrt());
Assert.AreEqual(100.0f, 10000.0f.ComplexSqrt());
}
[TestMethod]
public void ComplexSqrt_ShouldBeImaginary_GivenNegativeValue()
{
Assert.AreEqual(new Complex(0, 1), (-1.0f).ComplexSqrt());
Assert.AreEqual(new Complex(0, 1.4142135f), (-2.0f).ComplexSqrt());
Assert.AreEqual(new Complex(0, 3.0f), (-9.0f).ComplexSqrt());
Assert.AreEqual(new Complex(0, 4.0f), (-16.0f).ComplexSqrt());
}
[TestMethod]
public void ComplexSqrt_ShouldBeComplexInfinity_GivenInfinity()
{
Assert.AreEqual(Complex.Infinity, float.NegativeInfinity.ComplexSqrt());
Assert.AreEqual(Complex.Infinity, float.PositiveInfinity.ComplexSqrt());
}
[TestMethod]
public void ComplexSqrt_ShouldBeNaN_GivenNaN()
{
Assert.AreEqual(Complex.NaN, float.NaN.ComplexSqrt());
}
[TestMethod]
public void IsEven_ShouldBeFalse_GivenOddNumber()
{
Assert.IsFalse((-3.0f).IsEven());
Assert.IsFalse((-1.0f).IsEven());
Assert.IsFalse(1.0f.IsEven());
Assert.IsFalse(3.0f.IsEven());
}
[TestMethod]
public void IsEven_ShouldBeTrue_GivenOddNumber()
{
Assert.IsTrue((-4.0f).IsEven());
Assert.IsTrue((-2.0f).IsEven());
Assert.IsTrue(0.0f.IsEven());
Assert.IsTrue(2.0f.IsEven());
Assert.IsTrue(4.0f.IsEven());
}
[TestMethod]
public void IsOdd_ShouldBeFalse_GivenEvenNumber()
{
Assert.IsFalse((-4.0f).IsOdd());
Assert.IsFalse((-2.0f).IsOdd());
Assert.IsFalse(0.0f.IsOdd());
Assert.IsFalse(2.0f.IsOdd());
Assert.IsFalse(4.0f.IsOdd());
}
[TestMethod]
public void IsOdd_ShouldBeTrue_GivenOddNumber()
{
Assert.IsTrue((-3.0f).IsOdd());
Assert.IsTrue((-1.0f).IsOdd());
Assert.IsTrue(1.0f.IsOdd());
Assert.IsTrue(3.0f.IsOdd());
}
[TestMethod]
public void Round_ShouldRoundToNearestInteger()
{
Assert.AreEqual(4.0f, 3.5f.Round());
Assert.AreEqual(7.0f, 6.8f.Round());
Assert.AreEqual(7.0f, 7.2f.Round());
}
[TestMethod]
public void Round_ShouldRoundToNearestMultiple()
{
Assert.AreEqual(5.0f, 3.5f.Round(5));
Assert.AreEqual(5.0f, 7.0f.Round(5));
Assert.AreEqual(10.0f, 7.5f.Round(5));
}
[TestMethod]
public void Sign_ShouldBeMinus1_GivenNegative()
{
Assert.AreEqual(-1, -1.0f.Sign());
Assert.AreEqual(-1, -2.0f.Sign());
Assert.AreEqual(-1, -3.0f.Sign());
}
[TestMethod]
public void Sign_ShouldBe0_Given0()
{
Assert.AreEqual(0, 0.0f.Sign());
}
[TestMethod]
public void Sign_ShouldBe1_GivenPositive()
{
Assert.AreEqual(1, 1.0f.Sign());
Assert.AreEqual(1, 2.0f.Sign());
Assert.AreEqual(1, 3.0f.Sign());
}
[TestMethod]
public void Sqrt_ShouldBeCorrect_GivenValue()
{
Assert.AreEqual(0.0f, 0.0f.Sqrt());
Assert.AreEqual(1.4142135f, 2.0f.Sqrt());
Assert.AreEqual(3.0f, 9.0f.Sqrt());
Assert.AreEqual(4.0f, 16.0f.Sqrt());
Assert.AreEqual(100.0f, 10000.0f.Sqrt());
}
[TestMethod]
public void Sqrt_ShouldBeNaN_GivenNaN()
{
Assert.AreEqual(float.NaN, float.NaN.Sqrt());
}
[TestMethod]
public void Sqrt_ShouldBeNaN_GivenNegativeValue()
{
Assert.AreEqual(float.NaN, (-1.0f).Sqrt());
Assert.AreEqual(float.NaN, (-2.0f).Sqrt());
Assert.AreEqual(float.NaN, (-3.0f).Sqrt());
Assert.AreEqual(float.NaN, float.NegativeInfinity.Sqrt());
}
[TestMethod]
public void Sqrt_ShouldBePositiveInfinity_GivenPositiveInfinity()
{
Assert.AreEqual(float.PositiveInfinity, float.PositiveInfinity.Sqrt());
}
[TestMethod]
public void Acos_ShouldBeCorrect()
{
Assert.AreEqual(1.0471975803375244f, 0.5f.Acos());
}
[TestMethod]
public void Acosh_ShouldBeCorrect()
{
Assert.AreEqual(0.9624236822128296f, 1.5f.Acosh());
}
[TestMethod]
public void Asin_ShouldBeCorrect()
{
Assert.AreEqual(0.5235987901687622f, 0.5f.Asin());
}
[TestMethod]
public void Asinh_ShouldBeCorrect()
{
Assert.AreEqual(1.19476318359375f, 1.5f.Asinh());
}
[TestMethod]
public void Atan_ShouldBeCorrect()
{
Assert.AreEqual(0.46364760398864746, 0.5f.Atan());
}
[TestMethod]
public void Atanh_ShouldBeCorrect()
{
Assert.AreEqual(0.5493061542510986f, 0.5f.Atanh());
}
[TestMethod]
public void Cos_ShouldBeCorrect()
{
Assert.AreEqual(0.8775825500488281f, 0.5f.Cos());
}
[TestMethod]
public void Cosh_ShouldBeCorrect()
{
Assert.AreEqual(2.352409601211548f, 1.5f.Cosh());
}
[TestMethod]
public void Sin_ShouldBeCorrect()
{
Assert.AreEqual(0.4794255495071411, 0.5f.Sin());
}
[TestMethod]
public void Sinh_ShouldBeCorrect()
{
Assert.AreEqual(2.129279375076294f, 1.5f.Sinh());
}
[TestMethod]
public void Tan_ShouldBeCorrect()
{
Assert.AreEqual(0.4794255495071411f, 0.5f.Tan());
}
[TestMethod]
public void Tanh_ShouldBeCorrect()
{
Assert.AreEqual(0.46211716532707214f, 0.5f.Tanh());
}
}

View File

@ -0,0 +1,175 @@
using System.Diagnostics.Contracts;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace X10D.Math;
/// <summary>
/// Extension methods for <see cref="decimal" />.
/// </summary>
public static class DecimalExtensions
{
/// <summary>
/// Returns the complex square root of this decimal number.
/// </summary>
/// <param name="value">The number whose square root is to be found.</param>
/// <returns>The square root of <paramref name="value" />.</returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static Complex ComplexSqrt(this decimal value)
{
return Complex.Sqrt((double)value);
}
/// <summary>
/// Returns a value indicating whether the current value is evenly divisible by 2.
/// </summary>
/// <param name="value">The value whose parity to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> is evenly divisible by 2, or <see langword="false" />
/// otherwise.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static bool IsEven(this decimal value)
{
return value % 2.0m == 0.0m;
}
/// <summary>
/// Returns a value indicating whether the current value is not evenly divisible by 2.
/// </summary>
/// <param name="value">The value whose parity to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> is not evenly divisible by 2, or <see langword="false" />
/// otherwise.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static bool IsOdd(this decimal value)
{
return !value.IsEven();
}
/// <summary>
/// Rounds the current value to the nearest whole number.
/// </summary>
/// <param name="value">The value to round.</param>
/// <returns><paramref name="value" /> rounded to the nearest whole number.</returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static decimal Round(this decimal value)
{
return value.Round(1.0m);
}
/// <summary>
/// Rounds the current value to the nearest multiple of a specified number.
/// </summary>
/// <param name="value">The value to round.</param>
/// <param name="nearest">The nearest multiple to which <paramref name="value" /> should be rounded.</param>
/// <returns><paramref name="value" /> rounded to the nearest multiple of <paramref name="nearest" />.</returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static decimal Round(this decimal value, decimal nearest)
{
return System.Math.Round(value / nearest) * nearest;
}
/// <summary>
/// Returns an integer that indicates the sign of this decimal number.
/// </summary>
/// <param name="value">A signed number.</param>
/// <returns>
/// A number that indicates the sign of <paramref name="value" />, as shown in the following table.
///
/// <list type="table">
/// <listheader>
/// <term>Return value</term>
/// <description>Meaning</description>
/// </listheader>
///
/// <item>
/// <term>-1</term>
/// <description><paramref name="value" /> is less than zero.</description>
/// </item>
/// <item>
/// <term>0</term>
/// <description><paramref name="value" /> is equal to zero.</description>
/// </item>
/// <item>
/// <term>1</term>
/// <description><paramref name="value" /> is greater than zero.</description>
/// </item>
/// </list>
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static int Sign(this decimal value)
{
return System.Math.Sign(value);
}
/// <summary>
/// Returns the square root of this double-precision floating-point number.
/// </summary>
/// <param name="value">The number whose square root is to be found.</param>
/// <returns>
/// One of the values in the following table.
///
/// <list type="table">
/// <listheader>
/// <term>Return value</term>
/// <description>Meaning</description>
/// </listheader>
///
/// <item>
/// <term>The positive square root of <paramref name="value" />.</term>
/// <description><paramref name="value" /> is greater than or equal to 0.</description>
/// </item>
/// <item>
/// <term><see cref="double.NaN" /></term>
/// <description><paramref name="value" /> is equal to <see cref="double.NaN" /> or is negative.</description>
/// </item>
/// <item>
/// <term><see cref="double.PositiveInfinity" /></term>
/// <description><paramref name="value" /> is equal to <see cref="double.PositiveInfinity" />.</description>
/// </item>
/// </list>
/// </returns>
/// <exception cref="ArgumentException"><paramref name="value" /> is negative.</exception>
/// <remarks>
/// For negative input, this method returns <see cref="double.NaN" />. To receive a complex number, see
/// <see cref="Numerics.DoubleExtensions.ComplexSqrt" />.
/// </remarks>
/// <seealso cref="Numerics.DoubleExtensions.ComplexSqrt" />
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static decimal Sqrt(this decimal value)
{
switch (value)
{
case 0:
return 0;
case < 0:
throw new ArgumentException("value cannot be negative", nameof(value));
}
decimal previous;
var current = (decimal)System.Math.Sqrt((double)value);
do
{
previous = current;
if (previous == 0.0m)
{
return 0;
}
current = (previous + value / previous) / 2;
} while (System.Math.Abs(previous - current) > 0.0m);
return current;
}
}

View File

@ -1,4 +1,5 @@
using System.Diagnostics.Contracts;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace X10D.Math;
@ -115,6 +116,32 @@ public static class DoubleExtensions
return System.Math.Atanh(value);
}
/// <summary>
/// Returns the complex square root of this double-precision floating-point number.
/// </summary>
/// <param name="value">The number whose square root is to be found.</param>
/// <returns>The square root of <paramref name="value" />.</returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static Complex ComplexSqrt(this double value)
{
switch (value)
{
case double.PositiveInfinity:
case double.NegativeInfinity:
return Complex.Infinity;
case double.NaN:
return Complex.NaN;
case 0:
return Complex.Zero;
case > 0:
return new Complex(System.Math.Sqrt(value), 0);
case < 0:
return new Complex(0, System.Math.Sqrt(-value));
}
}
/// <summary>
/// Returns the cosine of the specified angle.
/// </summary>

View File

@ -1,4 +1,5 @@
using System.Diagnostics.Contracts;
using System.Numerics;
using System.Runtime.CompilerServices;
namespace X10D.Math;
@ -115,6 +116,32 @@ public static class SingleExtensions
return MathF.Atanh(value);
}
/// <summary>
/// Returns the complex square root of this single-precision floating-point number.
/// </summary>
/// <param name="value">The number whose square root is to be found.</param>
/// <returns>The square root of <paramref name="value" />.</returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static Complex ComplexSqrt(this float value)
{
switch (value)
{
case float.PositiveInfinity:
case float.NegativeInfinity:
return Complex.Infinity;
case float.NaN:
return Complex.NaN;
case 0:
return Complex.Zero;
case > 0:
return new Complex(MathF.Sqrt(value), 0);
case < 0:
return new Complex(0, MathF.Sqrt(-value));
}
}
/// <summary>
/// Returns the cosine of the specified angle.
/// </summary>

View File

@ -1,35 +0,0 @@
using System.Diagnostics.Contracts;
using System.Numerics;
using System.Runtime.CompilerServices;
using X10D.Math;
namespace X10D.Numerics;
/// <summary>
/// Extension methods for <see cref="double" />.
/// </summary>
public static class DoubleExtensions
{
/// <summary>
/// Returns the complex square root of this double-precision floating-point number.
/// </summary>
/// <param name="value">The number whose square root is to be found.</param>
/// <returns>The square root of <paramref name="value" />.</returns>
/// <seealso cref="X10D.Math.DoubleExtensions.Sqrt" />
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static Complex ComplexSqrt(this double value)
{
switch (value)
{
case double.PositiveInfinity:
case double.NegativeInfinity:
return Complex.Infinity;
case double.NaN:
return Complex.NaN;
}
double absoluteSqrt = System.Math.Abs(value).Sqrt();
return new Complex(absoluteSqrt, value >= 0 ? 0 : 1);
}
}

View File

@ -1,35 +0,0 @@
using System.Diagnostics.Contracts;
using System.Numerics;
using System.Runtime.CompilerServices;
using X10D.Math;
namespace X10D.Numerics;
/// <summary>
/// Extension methods for <see cref="float" />.
/// </summary>
public static class SingleExtensions
{
/// <summary>
/// Returns the complex square root of this single-precision floating-point number.
/// </summary>
/// <param name="value">The number whose square root is to be found.</param>
/// <returns>The square root of <paramref name="value" />.</returns>
/// <seealso cref="X10D.Math.SingleExtensions.Sqrt" />
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static Complex ComplexSqrt(this float value)
{
switch (value)
{
case float.PositiveInfinity:
case float.NegativeInfinity:
return Complex.Infinity;
case float.NaN:
return Complex.NaN;
}
float absoluteSqrt = MathF.Abs(value).Sqrt();
return new Complex(absoluteSqrt, value >= 0 ? 0 : 1);
}
}