1
0
mirror of https://github.com/oliverbooth/X10D synced 2024-11-22 19:18:46 +00:00

Add tests for IsEven/IsOdd/DigitalRoot

This commit is contained in:
Oliver Booth 2022-04-25 00:02:08 +01:00
parent 60e367f8a8
commit 7fb9459a91
No known key found for this signature in database
GPG Key ID: 32A00B35503AF634
22 changed files with 1121 additions and 690 deletions

View File

@ -6,6 +6,14 @@ namespace X10D.Tests.Math;
[TestClass]
public class ByteTests
{
[TestMethod]
public void DigitalRootShouldBeCorrect()
{
const byte value = 238;
Assert.AreEqual(4, value.DigitalRoot());
Assert.AreEqual(4, (-value).DigitalRoot());
}
[TestMethod]
public void FactorialShouldBeCorrect()
{
@ -28,11 +36,8 @@ public class ByteTests
const byte one = 1;
const byte two = 2;
bool oneEven = one.IsEven();
bool twoEven = two.IsEven();
Assert.IsFalse(oneEven);
Assert.IsTrue(twoEven);
Assert.IsFalse(one.IsEven());
Assert.IsTrue(two.IsEven());
}
[TestMethod]
@ -41,10 +46,7 @@ public class ByteTests
const byte one = 1;
const byte two = 2;
bool oneOdd = one.IsOdd();
bool twoOdd = two.IsOdd();
Assert.IsTrue(oneOdd);
Assert.IsFalse(twoOdd);
Assert.IsTrue(one.IsOdd());
Assert.IsFalse(two.IsOdd());
}
}

View File

@ -6,6 +6,14 @@ namespace X10D.Tests.Math;
[TestClass]
public class Int16Tests
{
[TestMethod]
public void DigitalRootShouldBeCorrect()
{
const short value = 238;
Assert.AreEqual(4, value.DigitalRoot());
Assert.AreEqual(4, (-value).DigitalRoot());
}
[TestMethod]
public void FactorialShouldBeCorrect()
{
@ -22,9 +30,39 @@ public class Int16Tests
Assert.AreEqual(3628800L, ((short)10).Factorial());
}
[TestMethod]
public void IsEvenShouldBeCorrect()
{
const short one = 1;
const short two = 2;
Assert.IsFalse(one.IsEven());
Assert.IsTrue(two.IsEven());
}
[TestMethod]
public void IsOddShouldBeCorrect()
{
const short one = 1;
const short two = 2;
Assert.IsTrue(one.IsOdd());
Assert.IsFalse(two.IsOdd());
}
[TestMethod]
public void NegativeFactorialShouldThrow()
{
Assert.ThrowsException<ArithmeticException>(() => ((short)-1).Factorial());
}
[TestMethod]
public void SignShouldBeCorrect()
{
const short one = 1;
const short zero = 0;
Assert.AreEqual(one, one.Sign());
Assert.AreEqual(zero, zero.Sign());
Assert.AreEqual(-one, (-one).Sign());
}
}

View File

@ -6,6 +6,14 @@ namespace X10D.Tests.Math;
[TestClass]
public class Int32Tests
{
[TestMethod]
public void DigitalRootShouldBeCorrect()
{
const int value = 238;
Assert.AreEqual(4, value.DigitalRoot());
Assert.AreEqual(4, (-value).DigitalRoot());
}
[TestMethod]
public void FactorialShouldBeCorrect()
{
@ -22,9 +30,39 @@ public class Int32Tests
Assert.AreEqual(3628800L, 10.Factorial());
}
[TestMethod]
public void IsEvenShouldBeCorrect()
{
const int one = 1;
const int two = 2;
Assert.IsFalse(one.IsEven());
Assert.IsTrue(two.IsEven());
}
[TestMethod]
public void IsOddShouldBeCorrect()
{
const int one = 1;
const int two = 2;
Assert.IsTrue(one.IsOdd());
Assert.IsFalse(two.IsOdd());
}
[TestMethod]
public void NegativeFactorialShouldThrow()
{
Assert.ThrowsException<ArithmeticException>(() => (-1).Factorial());
}
[TestMethod]
public void SignShouldBeCorrect()
{
const int one = 1;
const int zero = 0;
Assert.AreEqual(one, one.Sign());
Assert.AreEqual(zero, zero.Sign());
Assert.AreEqual(-one, (-one).Sign());
}
}

View File

@ -6,6 +6,14 @@ namespace X10D.Tests.Math;
[TestClass]
public class Int64Tests
{
[TestMethod]
public void DigitalRootShouldBeCorrect()
{
const long value = 238;
Assert.AreEqual(4, value.DigitalRoot());
Assert.AreEqual(4, (-value).DigitalRoot());
}
[TestMethod]
public void FactorialShouldBeCorrect()
{
@ -22,9 +30,39 @@ public class Int64Tests
Assert.AreEqual(3628800L, 10L.Factorial());
}
[TestMethod]
public void IsEvenShouldBeCorrect()
{
const long one = 1;
const long two = 2;
Assert.IsFalse(one.IsEven());
Assert.IsTrue(two.IsEven());
}
[TestMethod]
public void IsOddShouldBeCorrect()
{
const long one = 1;
const long two = 2;
Assert.IsTrue(one.IsOdd());
Assert.IsFalse(two.IsOdd());
}
[TestMethod]
public void NegativeFactorialShouldThrow()
{
Assert.ThrowsException<ArithmeticException>(() => (-1L).Factorial());
}
[TestMethod]
public void SignShouldBeCorrect()
{
const long one = 1;
const long zero = 0;
Assert.AreEqual(one, one.Sign());
Assert.AreEqual(zero, zero.Sign());
Assert.AreEqual(-one, (-one).Sign());
}
}

View File

@ -7,6 +7,14 @@ namespace X10D.Tests.Math;
[CLSCompliant(false)]
public class SByteTests
{
[TestMethod]
public void DigitalRootShouldBeCorrect()
{
const sbyte value = 127; // sbyte.MaxValue. can't use 238 like the other tests
Assert.AreEqual(1, value.DigitalRoot());
Assert.AreEqual(1, (-value).DigitalRoot());
}
[TestMethod]
public void FactorialShouldBeCorrect()
{
@ -28,12 +36,9 @@ public class SByteTests
{
const sbyte one = 1;
const sbyte two = 2;
bool oneEven = one.IsEven();
bool twoEven = two.IsEven();
Assert.AreEqual(false, oneEven);
Assert.AreEqual(true, twoEven);
Assert.IsFalse(one.IsEven());
Assert.IsTrue(two.IsEven());
}
[TestMethod]
@ -41,12 +46,9 @@ public class SByteTests
{
const sbyte one = 1;
const sbyte two = 2;
bool oneOdd = one.IsOdd();
bool twoOdd = two.IsOdd();
Assert.AreEqual(true, oneOdd);
Assert.AreEqual(false, twoOdd);
Assert.IsTrue(one.IsOdd());
Assert.IsFalse(two.IsOdd());
}
[TestMethod]
@ -54,4 +56,14 @@ public class SByteTests
{
Assert.ThrowsException<ArithmeticException>(() => ((sbyte)-1).Factorial());
}
[TestMethod]
public void SignShouldBeCorrect()
{
const sbyte one = 1;
const sbyte zero = 0;
Assert.AreEqual(one, one.Sign());
Assert.AreEqual(zero, zero.Sign());
Assert.AreEqual(-one, (-one).Sign());
}
}

View File

@ -7,6 +7,14 @@ namespace X10D.Tests.Math;
[CLSCompliant(false)]
public class UInt16Tests
{
[TestMethod]
public void DigitalRootShouldBeCorrect()
{
const ushort value = 238;
Assert.AreEqual(4, value.DigitalRoot());
Assert.AreEqual(4, (-value).DigitalRoot());
}
[TestMethod]
public void FactorialShouldBeCorrect()
{
@ -22,4 +30,24 @@ public class UInt16Tests
Assert.AreEqual(362880UL, ((ushort)9).Factorial());
Assert.AreEqual(3628800UL, ((ushort)10).Factorial());
}
[TestMethod]
public void IsEvenShouldBeCorrect()
{
const ushort one = 1;
const ushort two = 2;
Assert.IsFalse(one.IsEven());
Assert.IsTrue(two.IsEven());
}
[TestMethod]
public void IsOddShouldBeCorrect()
{
const ushort one = 1;
const ushort two = 2;
Assert.IsTrue(one.IsOdd());
Assert.IsFalse(two.IsOdd());
}
}

View File

@ -7,6 +7,14 @@ namespace X10D.Tests.Math;
[CLSCompliant(false)]
public class UInt32Tests
{
[TestMethod]
public void DigitalRootShouldBeCorrect()
{
const uint value = 238;
Assert.AreEqual(4U, value.DigitalRoot());
Assert.AreEqual(4U, (-value).DigitalRoot());
}
[TestMethod]
public void FactorialShouldBeCorrect()
{
@ -22,4 +30,24 @@ public class UInt32Tests
Assert.AreEqual(362880UL, 9U.Factorial());
Assert.AreEqual(3628800UL, 10U.Factorial());
}
[TestMethod]
public void IsEvenShouldBeCorrect()
{
const uint one = 1;
const uint two = 2;
Assert.IsFalse(one.IsEven());
Assert.IsTrue(two.IsEven());
}
[TestMethod]
public void IsOddShouldBeCorrect()
{
const uint one = 1;
const uint two = 2;
Assert.IsTrue(one.IsOdd());
Assert.IsFalse(two.IsOdd());
}
}

View File

@ -7,6 +7,18 @@ namespace X10D.Tests.Math;
[CLSCompliant(false)]
public class UInt64Tests
{
[TestMethod]
public void DigitalRootShouldBeCorrect()
{
const ulong value = 238;
Assert.AreEqual(4U, value.DigitalRoot());
// -ulong operator not defined because it might exceed long.MinValue,
// so instead, cast to long and then negate.
// HAX.
Assert.AreEqual(4U, (-(long)value).DigitalRoot());
}
[TestMethod]
public void FactorialShouldBeCorrect()
{
@ -22,4 +34,24 @@ public class UInt64Tests
Assert.AreEqual(362880UL, 9UL.Factorial());
Assert.AreEqual(3628800UL, 10UL.Factorial());
}
[TestMethod]
public void IsEvenShouldBeCorrect()
{
const ulong one = 1;
const ulong two = 2;
Assert.IsFalse(one.IsEven());
Assert.IsTrue(two.IsEven());
}
[TestMethod]
public void IsOddShouldBeCorrect()
{
const ulong one = 1;
const ulong two = 2;
Assert.IsTrue(one.IsOdd());
Assert.IsFalse(two.IsOdd());
}
}

View File

@ -10,56 +10,6 @@ namespace X10D;
/// </summary>
public static class Int16Extensions
{
/// <summary>
/// Computes the digital root of an integer.
/// </summary>
/// <param name="value">The value whose digital root to compute.</param>
/// <returns>The digital root of <paramref name="value" />.</returns>
/// <remarks>The digital root is defined as the recursive sum of digits until that result is a single digit.</remarks>
public static short DigitalRoot(this short value)
{
short root = value.Mod(9);
return root < 1 ? (short)(9 - root) : root;
}
/// <summary>
/// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value.
/// </summary>
/// <param name="value">
/// A Unix time, expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z (January 1, 1970, at
/// 12:00 AM UTC). For Unix times before this date, its value is negative.
/// </param>
/// <returns>A date and time value that represents the same moment in time as the Unix time.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <para><paramref name="value" /> is less than -62,135,596,800,000.</para>
/// -or-
/// <para><paramref name="value" /> is greater than 253,402,300,799,999.</para>
/// </exception>
public static DateTimeOffset FromUnixTimeMilliseconds(this short value)
{
return DateTimeOffset.FromUnixTimeMilliseconds(value);
}
/// <summary>
/// Converts a Unix time expressed as the number of seconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value.
/// </summary>
/// <param name="value">
/// A Unix time, expressed as the number of seconds that have elapsed since 1970-01-01T00:00:00Z (January 1, 1970, at
/// 12:00 AM UTC). For Unix times before this date, its value is negative.
/// </param>
/// <returns>A date and time value that represents the same moment in time as the Unix time.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <para><paramref name="value" /> is less than -62,135,596,800.</para>
/// -or-
/// <para><paramref name="value" /> is greater than 253,402,300,799.</para>
/// </exception>
public static DateTimeOffset FromUnixTimeSeconds(this short value)
{
return DateTimeOffset.FromUnixTimeSeconds(value);
}
/// <summary>
/// Returns the current 16-bit signed integer value as an array of bytes.
/// </summary>
@ -70,182 +20,6 @@ public static class Int16Extensions
return BitConverter.GetBytes(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>
public static bool IsEven(this short value)
{
return (value & 1) == 0;
}
/// <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>
public static bool IsOdd(this short value)
{
return !value.IsEven();
}
/// <summary>
/// Returns a value indicating whether the current value is a prime number.
/// </summary>
/// <param name="value">The value whose primality to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> is prime; otherwise, <see langword="false" />.
/// </returns>
public static bool IsPrime(this short value)
{
return ((long)value).IsPrime();
}
/// <summary>
/// Linearly interpolates to the current value from a specified source using a specified alpha.
/// </summary>
/// <param name="target">The interpolation target.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static double LerpFrom(this short target, double value, double alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to the current value from a specified source using a specified alpha.
/// </summary>
/// <param name="target">The interpolation target.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static float LerpFrom(this short target, float value, float alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates from the current value to a specified target using a specified alpha.
/// </summary>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static double LerpTo(this short value, double target, double alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates from the current value to a specified target using a specified alpha.
/// </summary>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static float LerpTo(this short value, float target, float alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to a specified target from a specified source, using the current value as the alpha value.
/// </summary>
/// <param name="alpha">The interpolation alpha.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static double LerpWith(this short alpha, double value, double target)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to a specified target from a specified source, using the current value as the alpha value.
/// </summary>
/// <param name="alpha">The interpolation alpha.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static float LerpWith(this short alpha, float value, float target)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Performs a modulo operation which supports a negative dividend.
/// </summary>
/// <param name="dividend">The dividend.</param>
/// <param name="divisor">The divisor.</param>
/// <returns>The result of <c>dividend mod divisor</c>.</returns>
/// <remarks>
/// The <c>%</c> operator (commonly called the modulo operator) in C# is not defined to be modulo, but is instead
/// remainder. This quirk inherently makes it difficult to use modulo in a negative context, as <c>x % y</c> where x is
/// negative will return a negative value, akin to <c>-(x % y)</c>, even if precedence is forced. This method provides a
/// modulo operation which supports negative dividends.
/// </remarks>
/// <author>ShreevatsaR, https://stackoverflow.com/a/1082938/1467293</author>
/// <license>CC-BY-SA 2.5</license>
public static short Mod(this short dividend, short divisor)
{
var r = (short)(dividend % divisor);
return (short)(r < 0 ? r + divisor : r);
}
/// <summary>
/// Returns an integer that indicates the sign of this 16-bit signed integer.
/// </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 short value)
{
return System.Math.Sign(value);
}
/// <summary>
/// Returns an enumerable collection of 16-bit signed integers that range from the current value to a specified value.
/// </summary>

View File

@ -1,4 +1,4 @@
using System.Diagnostics.Contracts;
using System.Diagnostics.Contracts;
using System.Net;
using System.Runtime.CompilerServices;
using X10D.Math;
@ -63,53 +63,13 @@ public static class Int32Extensions
}
/// <summary>
/// Computes the digital root of an integer.
/// Converts the current angle in degrees to its equivalent represented in radians.
/// </summary>
/// <param name="value">The value whose digital root to compute.</param>
/// <returns>The digital root of <paramref name="value" />.</returns>
/// <remarks>The digital root is defined as the recursive sum of digits until that result is a single digit.</remarks>
public static int DigitalRoot(this int value)
/// <param name="value">The angle in degrees to convert.</param>
/// <returns>The result of π * <paramref name="value" /> / 180.</returns>
public static float DegreesToRadians(this int value)
{
int root = value.Mod(9);
return root < 1 ? 9 - root : root;
}
/// <summary>
/// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value.
/// </summary>
/// <param name="value">
/// A Unix time, expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z (January 1,
/// 1970, at 12:00 AM UTC). For Unix times before this date, its value is negative.
/// </param>
/// <returns>A date and time value that represents the same moment in time as the Unix time.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <para><paramref name="value" /> is less than -62,135,596,800,000.</para>
/// -or-
/// <para><paramref name="value" /> is greater than 253,402,300,799,999.</para>
/// </exception>
public static DateTimeOffset FromUnixTimeMilliseconds(this int value)
{
return DateTimeOffset.FromUnixTimeMilliseconds(value);
}
/// <summary>
/// Converts a Unix time expressed as the number of seconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value.
/// </summary>
/// <param name="value">
/// A Unix time, expressed as the number of seconds that have elapsed since 1970-01-01T00:00:00Z (January 1, 1970, at
/// 12:00 AM UTC). For Unix times before this date, its value is negative.
/// </param>
/// <returns>A date and time value that represents the same moment in time as the Unix time.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <para><paramref name="value" /> is less than -62,135,596,800.</para>
/// -or-
/// <para><paramref name="value" /> is greater than 253,402,300,799.</para>
/// </exception>
public static DateTimeOffset FromUnixTimeSeconds(this int value)
{
return DateTimeOffset.FromUnixTimeSeconds(value);
return ((float)value).DegreesToRadians();
}
/// <summary>
@ -122,148 +82,6 @@ public static class Int32Extensions
return BitConverter.GetBytes(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>
public static bool IsEven(this int value)
{
return (value & 1) == 0;
}
/// <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>
public static bool IsOdd(this int value)
{
return !value.IsEven();
}
/// <summary>
/// Returns a value indicating whether the current value is a prime number.
/// </summary>
/// <param name="value">The value whose primality to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> is prime; otherwise, <see langword="false" />.
/// </returns>
public static bool IsPrime(this int value)
{
return ((long)value).IsPrime();
}
/// <summary>
/// Linearly interpolates to the current value from a specified source using a specified alpha.
/// </summary>
/// <param name="target">The interpolation target.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static double LerpFrom(this int target, double value, double alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to the current value from a specified source using a specified alpha.
/// </summary>
/// <param name="target">The interpolation target.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static float LerpFrom(this int target, float value, float alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates from the current value to a specified target using a specified alpha.
/// </summary>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static double LerpTo(this int value, double target, double alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates from the current value to a specified target using a specified alpha.
/// </summary>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static float LerpTo(this int value, float target, float alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to a specified target from a specified source, using the current value as the alpha value.
/// </summary>
/// <param name="alpha">The interpolation alpha.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static double LerpWith(this int alpha, double value, double target)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to a specified target from a specified source, using the current value as the alpha value.
/// </summary>
/// <param name="alpha">The interpolation alpha.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static float LerpWith(this int alpha, float value, float target)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Performs a modulo operation which supports a negative dividend.
/// </summary>
/// <param name="dividend">The dividend.</param>
/// <param name="divisor">The divisor.</param>
/// <returns>The result of <c>dividend mod divisor</c>.</returns>
/// <remarks>
/// The <c>%</c> operator (commonly called the modulo operator) in C# is not defined to be modulo, but is instead
/// remainder. This quirk inherently makes it difficult to use modulo in a negative context, as <c>x % y</c> where x is
/// negative will return a negative value, akin to <c>-(x % y)</c>, even if precedence is forced. This method provides a
/// modulo operation which supports negative dividends.
/// </remarks>
/// <author>ShreevatsaR, https://stackoverflow.com/a/1082938/1467293</author>
/// <license>CC-BY-SA 2.5</license>
public static int Mod(this int dividend, int divisor)
{
int r = dividend % divisor;
return r < 0 ? r + divisor : r;
}
/// <summary>
/// Returns an integer that indicates the sign of this 32-bit signed integer.
/// </summary>

View File

@ -1,7 +1,4 @@
using System.Diagnostics.Contracts;
using System.Net;
using System.Runtime.CompilerServices;
using X10D.Math;
using System.Net;
namespace X10D;
@ -10,56 +7,6 @@ namespace X10D;
/// </summary>
public static class Int64Extensions
{
/// <summary>
/// Computes the digital root of an integer.
/// </summary>
/// <param name="value">The value whose digital root to compute.</param>
/// <returns>The digital root of <paramref name="value" />.</returns>
/// <remarks>The digital root is defined as the recursive sum of digits until that result is a single digit.</remarks>
public static long DigitalRoot(this long value)
{
long root = value.Mod(9);
return root < 1 ? 9 - root : root;
}
/// <summary>
/// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value.
/// </summary>
/// <param name="value">
/// A Unix time, expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z (January 1,
/// 1970, at 12:00 AM UTC). For Unix times before this date, its value is negative.
/// </param>
/// <returns>A date and time value that represents the same moment in time as the Unix time.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <para><paramref name="value" /> is less than -62,135,596,800,000.</para>
/// -or-
/// <para><paramref name="value" /> is greater than 253,402,300,799,999.</para>
/// </exception>
public static DateTimeOffset FromUnixTimeMilliseconds(this long value)
{
return DateTimeOffset.FromUnixTimeMilliseconds(value);
}
/// <summary>
/// Converts a Unix time expressed as the number of seconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value.
/// </summary>
/// <param name="value">
/// A Unix time, expressed as the number of seconds that have elapsed since 1970-01-01T00:00:00Z (January 1, 1970, at
/// 12:00 AM UTC). For Unix times before this date, its value is negative.
/// </param>
/// <returns>A date and time value that represents the same moment in time as the Unix time.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <para><paramref name="value" /> is less than -62,135,596,800.</para>
/// -or-
/// <para><paramref name="value" /> is greater than 253,402,300,799.</para>
/// </exception>
public static DateTimeOffset FromUnixTimeSeconds(this long value)
{
return DateTimeOffset.FromUnixTimeSeconds(value);
}
/// <summary>
/// Returns the current 64-bit signed integer value as an array of bytes.
/// </summary>
@ -71,204 +18,49 @@ public static class Int64Extensions
}
/// <summary>
/// Returns a value indicating whether the current value is evenly divisible by 2.
/// Returns the multiplicative persistence of a specified value.
/// </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>
public static bool IsEven(this long value)
{
return (value & 1) == 0;
}
/// <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>
public static bool IsOdd(this long value)
{
return !value.IsEven();
}
/// <summary>
/// Returns a value indicating whether the current value is a prime number.
/// </summary>
/// <param name="value">The value whose primality to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> is prime; otherwise, <see langword="false" />.
/// </returns>
public static bool IsPrime(this long value)
{
switch (value)
{
case < 2: return false;
case 2:
case 3: return true;
}
if (value % 2 == 0 || value % 3 == 0)
{
return false;
}
if ((value + 1) % 6 != 0 && (value - 1) % 6 != 0)
{
return false;
}
for (var iterator = 5L; iterator * iterator <= value; iterator += 6)
{
if (value % iterator == 0 || value % (iterator + 2) == 0)
{
return false;
}
}
return true;
}
/// <summary>
/// Linearly interpolates to the current value from a specified source using a specified alpha.
/// </summary>
/// <param name="target">The interpolation target.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static double LerpFrom(this long target, double value, double alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to the current value from a specified source using a specified alpha.
/// </summary>
/// <param name="target">The interpolation target.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static float LerpFrom(this long target, float value, float alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates from the current value to a specified target using a specified alpha.
/// </summary>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static double LerpTo(this long value, double target, double alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates from the current value to a specified target using a specified alpha.
/// </summary>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static float LerpTo(this long value, float target, float alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to a specified target from a specified source, using the current value as the alpha value.
/// </summary>
/// <param name="alpha">The interpolation alpha.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static double LerpWith(this long alpha, double value, double target)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to a specified target from a specified source, using the current value as the alpha value.
/// </summary>
/// <param name="alpha">The interpolation alpha.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
public static float LerpWith(this long alpha, float value, float target)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Performs a modulo operation which supports a negative dividend.
/// </summary>
/// <param name="dividend">The dividend.</param>
/// <param name="divisor">The divisor.</param>
/// <returns>The result of <c>dividend mod divisor</c>.</returns>
/// <param name="value">The value whose multiplicative persistence to calculate.</param>
/// <returns>The multiplicative persistence.</returns>
/// <remarks>
/// The <c>%</c> operator (commonly called the modulo operator) in C# is not defined to be modulo, but is instead
/// remainder. This quirk inherently makes it difficult to use modulo in a negative context, as <c>x % y</c> where x is
/// negative will return a negative value, akin to <c>-(x % y)</c>, even if precedence is forced. This method provides a
/// modulo operation which supports negative dividends.
/// Multiplicative persistence is defined as the recursive digital product until that product is a single digit.
/// </remarks>
/// <author>ShreevatsaR, https://stackoverflow.com/a/1082938/1467293</author>
/// <license>CC-BY-SA 2.5</license>
public static long Mod(this long dividend, long divisor)
public static int MultiplicativePersistence(this long value)
{
long r = dividend % divisor;
return r < 0 ? r + divisor : r;
}
var persistence = 0;
long product = value;
/// <summary>
/// Returns an integer that indicates the sign of this 64-bit signed integer.
/// </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 long value)
{
return System.Math.Sign(value);
const string foo = "Hello" + "World";
while (product > 9)
{
if (value % 10 == 0)
{
return persistence + 1;
}
while (value > 9)
{
value /= 10;
if (value % 10 == 0)
{
return persistence + 1;
}
}
long newProduct = 1;
long currentProduct = product;
while (currentProduct > 0)
{
newProduct *= currentProduct % 10;
currentProduct /= 10;
}
product = newProduct;
persistence++;
}
return persistence;
}
/// <summary>

View File

@ -1,10 +1,31 @@
namespace X10D.Math;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
namespace X10D.Math;
/// <summary>
/// Math-related extension methods for <see cref="byte" />.
/// </summary>
public static class ByteExtensions
{
/// <summary>
/// Computes the digital root of this 16-bit integer.
/// </summary>
/// <param name="value">The value whose digital root to compute.</param>
/// <returns>The digital root of <paramref name="value" />.</returns>
/// <remarks>The digital root is defined as the recursive sum of digits until that result is a single digit.</remarks>
/// <remarks>
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
/// </remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static byte DigitalRoot(this byte value)
{
int root = value % 9;
return (byte)(root == 0 ? 9 : root);
}
/// <summary>
/// Returns the factorial of the current 8-bit unsigned integer.
/// </summary>

View File

@ -1,16 +1,38 @@
namespace X10D.Math;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
namespace X10D.Math;
/// <summary>
/// Extension methods for <see cref="short" />.
/// </summary>
public static class Int16Extensions
{
/// <summary>
/// Computes the digital root of this 16-bit integer.
/// </summary>
/// <param name="value">The value whose digital root to compute.</param>
/// <returns>The digital root of <paramref name="value" />.</returns>
/// <remarks>
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
/// </remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static short DigitalRoot(this short value)
{
short root = System.Math.Abs(value).Mod(9);
return root < 1 ? (short)(9 - root) : root;
}
/// <summary>
/// Returns the factorial of the current 16-bit signed integer.
/// </summary>
/// <param name="value">The value whose factorial to compute.</param>
/// <returns>The factorial of <paramref name="value" />.</returns>
/// <exception cref="ArithmeticException"><paramref name="value" /> is less than 0.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static long Factorial(this short value)
{
if (value < 0)
@ -31,4 +53,152 @@ public static class Int16Extensions
return result;
}
/// <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 short value)
{
return (value & 1) == 0;
}
/// <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 short value)
{
return !value.IsEven();
}
/// <summary>
/// Returns a value indicating whether the current value is a prime number.
/// </summary>
/// <param name="value">The value whose primality to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> is prime; otherwise, <see langword="false" />.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static bool IsPrime(this short value)
{
return ((long)value).IsPrime();
}
/// <summary>
/// Linearly interpolates to the current value from a specified source using a specified alpha.
/// </summary>
/// <param name="target">The interpolation target.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static double LerpFrom(this short target, double value, double alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to the current value from a specified source using a specified alpha.
/// </summary>
/// <param name="target">The interpolation target.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static float LerpFrom(this short target, float value, float alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates from the current value to a specified target using a specified alpha.
/// </summary>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static double LerpTo(this short value, double target, double alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Performs a modulo operation which supports a negative dividend.
/// </summary>
/// <param name="dividend">The dividend.</param>
/// <param name="divisor">The divisor.</param>
/// <returns>The result of <c>dividend mod divisor</c>.</returns>
/// <remarks>
/// The <c>%</c> operator (commonly called the modulo operator) in C# is not defined to be modulo, but is instead
/// remainder. This quirk inherently makes it difficult to use modulo in a negative context, as <c>x % y</c> where x is
/// negative will return a negative value, akin to <c>-(x % y)</c>, even if precedence is forced. This method provides a
/// modulo operation which supports negative dividends.
/// </remarks>
/// <author>ShreevatsaR, https://stackoverflow.com/a/1082938/1467293</author>
/// <license>CC-BY-SA 2.5</license>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static short Mod(this short dividend, short divisor)
{
int r = dividend % divisor;
return (short)(r < 0 ? r + divisor : r);
}
/// <summary>
/// Returns an integer that indicates the sign of this 16-bit signed integer.
/// </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 short value)
{
return System.Math.Sign(value);
}
}

View File

@ -1,16 +1,38 @@
namespace X10D.Math;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
namespace X10D.Math;
/// <summary>
/// Extension methods for <see cref="int" />.
/// </summary>
public static class Int32Extensions
{
/// <summary>
/// Computes the digital root of this 32-bit integer.
/// </summary>
/// <param name="value">The value whose digital root to compute.</param>
/// <returns>The digital root of <paramref name="value" />.</returns>
/// <remarks>
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
/// </remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static int DigitalRoot(this int value)
{
int root = System.Math.Abs(value).Mod(9);
return root < 1 ? 9 - root : root;
}
/// <summary>
/// Returns the factorial of the current 32-bit signed integer.
/// </summary>
/// <param name="value">The value whose factorial to compute.</param>
/// <returns>The factorial of <paramref name="value" />.</returns>
/// <exception cref="ArithmeticException"><paramref name="value" /> is less than 0.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static long Factorial(this int value)
{
if (value < 0)
@ -31,4 +53,166 @@ public static class Int32Extensions
return result;
}
/// <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 int value)
{
return (value & 1) == 0;
}
/// <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 int value)
{
return !value.IsEven();
}
/// <summary>
/// Returns a value indicating whether the current value is a prime number.
/// </summary>
/// <param name="value">The value whose primality to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> is prime; otherwise, <see langword="false" />.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static bool IsPrime(this int value)
{
return ((long)value).IsPrime();
}
/// <summary>
/// Linearly interpolates to the current value from a specified source using a specified alpha.
/// </summary>
/// <param name="target">The interpolation target.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static double LerpFrom(this int target, double value, double alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to the current value from a specified source using a specified alpha.
/// </summary>
/// <param name="target">The interpolation target.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static float LerpFrom(this int target, float value, float alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates from the current value to a specified target using a specified alpha.
/// </summary>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static double LerpTo(this int value, double target, double alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates from the current value to a specified target using a specified alpha.
/// </summary>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static float LerpTo(this int value, float target, float alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to a specified target from a specified source, using the current value as the alpha value.
/// </summary>
/// <param name="alpha">The interpolation alpha.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static double LerpWith(this int alpha, double value, double target)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to a specified target from a specified source, using the current value as the alpha value.
/// </summary>
/// <param name="alpha">The interpolation alpha.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static float LerpWith(this int alpha, float value, float target)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Performs a modulo operation which supports a negative dividend.
/// </summary>
/// <param name="dividend">The dividend.</param>
/// <param name="divisor">The divisor.</param>
/// <returns>The result of <c>dividend mod divisor</c>.</returns>
/// <remarks>
/// The <c>%</c> operator (commonly called the modulo operator) in C# is not defined to be modulo, but is instead
/// remainder. This quirk inherently makes it difficult to use modulo in a negative context, as <c>x % y</c> where x is
/// negative will return a negative value, akin to <c>-(x % y)</c>, even if precedence is forced. This method provides a
/// modulo operation which supports negative dividends.
/// </remarks>
/// <author>ShreevatsaR, https://stackoverflow.com/a/1082938/1467293</author>
/// <license>CC-BY-SA 2.5</license>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static int Mod(this int dividend, int divisor)
{
int r = dividend % divisor;
return r < 0 ? r + divisor : r;
}
}

View File

@ -1,16 +1,38 @@
namespace X10D.Math;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
namespace X10D.Math;
/// <summary>
/// Extension methods for <see cref="long" />.
/// </summary>
public static class Int64Extensions
{
/// <summary>
/// Computes the digital root of this 64-bit integer.
/// </summary>
/// <param name="value">The value whose digital root to compute.</param>
/// <returns>The digital root of <paramref name="value" />.</returns>
/// <remarks>
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
/// </remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static long DigitalRoot(this long value)
{
long root = System.Math.Abs(value).Mod(9L);
return root < 1L ? 9L - root : root;
}
/// <summary>
/// Returns the factorial of the current 64-bit signed integer.
/// </summary>
/// <param name="value">The value whose factorial to compute.</param>
/// <returns>The factorial of <paramref name="value" />.</returns>
/// <exception cref="ArithmeticException"><paramref name="value" /> is less than 0.</exception>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static long Factorial(this long value)
{
if (value < 0)
@ -31,4 +53,225 @@ public static class Int64Extensions
return result;
}
/// <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 long value)
{
return (value & 1) == 0;
}
/// <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 long value)
{
return !value.IsEven();
}
/// <summary>
/// Returns a value indicating whether the current value is a prime number.
/// </summary>
/// <param name="value">The value whose primality to check.</param>
/// <returns>
/// <see langword="true" /> if <paramref name="value" /> is prime; otherwise, <see langword="false" />.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static bool IsPrime(this long value)
{
switch (value)
{
case < 2: return false;
case 2:
case 3: return true;
}
if (value % 2 == 0 || value % 3 == 0)
{
return false;
}
if ((value + 1) % 6 != 0 && (value - 1) % 6 != 0)
{
return false;
}
for (var iterator = 5L; iterator * iterator <= value; iterator += 6)
{
if (value % iterator == 0 || value % (iterator + 2) == 0)
{
return false;
}
}
return true;
}
/// <summary>
/// Linearly interpolates to the current value from a specified source using a specified alpha.
/// </summary>
/// <param name="target">The interpolation target.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static double LerpFrom(this long target, double value, double alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to the current value from a specified source using a specified alpha.
/// </summary>
/// <param name="target">The interpolation target.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static float LerpFrom(this long target, float value, float alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates from the current value to a specified target using a specified alpha.
/// </summary>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static double LerpTo(this long value, double target, double alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates from the current value to a specified target using a specified alpha.
/// </summary>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <param name="alpha">The interpolation alpha.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static float LerpTo(this long value, float target, float alpha)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to a specified target from a specified source, using the current value as the alpha value.
/// </summary>
/// <param name="alpha">The interpolation alpha.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static double LerpWith(this long alpha, double value, double target)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Linearly interpolates to a specified target from a specified source, using the current value as the alpha value.
/// </summary>
/// <param name="alpha">The interpolation alpha.</param>
/// <param name="value">The interpolation source.</param>
/// <param name="target">The interpolation target.</param>
/// <returns>
/// The interpolation result as determined by <c>(1 - alpha) * value + alpha * target</c>.
/// </returns>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static float LerpWith(this long alpha, float value, float target)
{
return MathUtility.Lerp(value, target, alpha);
}
/// <summary>
/// Performs a modulo operation which supports a negative dividend.
/// </summary>
/// <param name="dividend">The dividend.</param>
/// <param name="divisor">The divisor.</param>
/// <returns>The result of <c>dividend mod divisor</c>.</returns>
/// <remarks>
/// The <c>%</c> operator (commonly called the modulo operator) in C# is not defined to be modulo, but is instead
/// remainder. This quirk inherently makes it difficult to use modulo in a negative context, as <c>x % y</c> where x is
/// negative will return a negative value, akin to <c>-(x % y)</c>, even if precedence is forced. This method provides a
/// modulo operation which supports negative dividends.
/// </remarks>
/// <author>ShreevatsaR, https://stackoverflow.com/a/1082938/1467293</author>
/// <license>CC-BY-SA 2.5</license>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static long Mod(this long dividend, long divisor)
{
long r = dividend % divisor;
return r < 0 ? r + divisor : r;
}
/// <summary>
/// Returns an integer that indicates the sign of this 64-bit signed integer.
/// </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 long value)
{
return System.Math.Sign(value);
}
}

View File

@ -9,6 +9,23 @@ namespace X10D.Math;
[CLSCompliant(false)]
public static class SByteExtensions
{
/// <summary>
/// Computes the digital root of this 32-bit integer.
/// </summary>
/// <param name="value">The value whose digital root to compute.</param>
/// <returns>The digital root of <paramref name="value" />.</returns>
/// <remarks>
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
/// </remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static sbyte DigitalRoot(this sbyte value)
{
int root = System.Math.Abs(value).Mod(9);
return (sbyte)(root < 1 ? 9 - root : root);
}
/// <summary>
/// Returns the factorial of the current 8-bit signed integer.
/// </summary>
@ -82,6 +99,28 @@ public static class SByteExtensions
return ((long)value).IsPrime();
}
/// <summary>
/// Performs a modulo operation which supports a negative dividend.
/// </summary>
/// <param name="dividend">The dividend.</param>
/// <param name="divisor">The divisor.</param>
/// <returns>The result of <c>dividend mod divisor</c>.</returns>
/// <remarks>
/// The <c>%</c> operator (commonly called the modulo operator) in C# is not defined to be modulo, but is instead
/// remainder. This quirk inherently makes it difficult to use modulo in a negative context, as <c>x % y</c> where x is
/// negative will return a negative value, akin to <c>-(x % y)</c>, even if precedence is forced. This method provides a
/// modulo operation which supports negative dividends.
/// </remarks>
/// <author>ShreevatsaR, https://stackoverflow.com/a/1082938/1467293</author>
/// <license>CC-BY-SA 2.5</license>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static sbyte Mod(this sbyte dividend, sbyte divisor)
{
int r = dividend % divisor;
return (sbyte)(r < 0 ? r + divisor : r);
}
/// <summary>
/// Returns an integer that indicates the sign of this 8-bit signed integer.
/// </summary>

View File

@ -1,4 +1,7 @@
namespace X10D.Math;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
namespace X10D.Math;
/// <summary>
/// Extension methods for <see cref="ushort" />.
@ -6,6 +9,23 @@
[CLSCompliant(false)]
public static class UInt16Extensions
{
/// <summary>
/// Computes the digital root of the current 16-bit unsigned integer.
/// </summary>
/// <param name="value">The value whose digital root to compute.</param>
/// <returns>The digital root of <paramref name="value" />.</returns>
/// <remarks>
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
/// </remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static ushort DigitalRoot(this ushort value)
{
var root = (ushort)(value % 9);
return (ushort)(root == 0 ? 9 : root);
}
/// <summary>
/// Returns the factorial of the current 16-bit unsigned integer.
/// </summary>

View File

@ -1,4 +1,7 @@
namespace X10D.Math;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
namespace X10D.Math;
/// <summary>
/// Extension methods for <see cref="uint" />.
@ -6,6 +9,23 @@
[CLSCompliant(false)]
public static class UInt32Extensions
{
/// <summary>
/// Computes the digital root of the current 32-bit unsigned integer.
/// </summary>
/// <param name="value">The value whose digital root to compute.</param>
/// <returns>The digital root of <paramref name="value" />.</returns>
/// <remarks>
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
/// </remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static uint DigitalRoot(this uint value)
{
uint root = value % 9;
return root == 0 ? 9 : root;
}
/// <summary>
/// Returns the factorial of the current 32-bit unsigned integer.
/// </summary>

View File

@ -1,4 +1,7 @@
namespace X10D.Math;
using System.Diagnostics.Contracts;
using System.Runtime.CompilerServices;
namespace X10D.Math;
/// <summary>
/// Extension methods for <see cref="ulong" />.
@ -6,6 +9,23 @@
[CLSCompliant(false)]
public static class UInt64Extensions
{
/// <summary>
/// Computes the digital root of the current 64-bit unsigned integer.
/// </summary>
/// <param name="value">The value whose digital root to compute.</param>
/// <returns>The digital root of <paramref name="value" />.</returns>
/// <remarks>
/// <para>The digital root is defined as the recursive sum of digits until that result is a single digit.</para>
/// <para>For example, the digital root of 239 is 5: <c>2 + 3 + 9 = 14</c>, then <c>1 + 4 = 5</c>.</para>
/// </remarks>
[Pure]
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
public static ulong DigitalRoot(this ulong value)
{
ulong root = value % 9;
return root == 0 ? 9 : root;
}
/// <summary>
/// Returns the factorial of the current 64-bit unsigned integer.
/// </summary>

View File

@ -5,6 +5,44 @@
/// </summary>
public static class Int16Extensions
{
/// <summary>
/// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value.
/// </summary>
/// <param name="value">
/// A Unix time, expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z (January 1, 1970, at
/// 12:00 AM UTC). For Unix times before this date, its value is negative.
/// </param>
/// <returns>A date and time value that represents the same moment in time as the Unix time.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <para><paramref name="value" /> is less than -62,135,596,800,000.</para>
/// -or-
/// <para><paramref name="value" /> is greater than 253,402,300,799,999.</para>
/// </exception>
public static DateTimeOffset FromUnixTimeMilliseconds(this short value)
{
return DateTimeOffset.FromUnixTimeMilliseconds(value);
}
/// <summary>
/// Converts a Unix time expressed as the number of seconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value.
/// </summary>
/// <param name="value">
/// A Unix time, expressed as the number of seconds that have elapsed since 1970-01-01T00:00:00Z (January 1, 1970, at
/// 12:00 AM UTC). For Unix times before this date, its value is negative.
/// </param>
/// <returns>A date and time value that represents the same moment in time as the Unix time.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <para><paramref name="value" /> is less than -62,135,596,800.</para>
/// -or-
/// <para><paramref name="value" /> is greater than 253,402,300,799.</para>
/// </exception>
public static DateTimeOffset FromUnixTimeSeconds(this short value)
{
return DateTimeOffset.FromUnixTimeSeconds(value);
}
/// <summary>
/// Returns a <see cref="TimeSpan" /> that represents this value as the number of ticks.
/// </summary>

View File

@ -5,6 +5,44 @@
/// </summary>
public static class Int32Extensions
{
/// <summary>
/// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value.
/// </summary>
/// <param name="value">
/// A Unix time, expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z (January 1,
/// 1970, at 12:00 AM UTC). For Unix times before this date, its value is negative.
/// </param>
/// <returns>A date and time value that represents the same moment in time as the Unix time.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <para><paramref name="value" /> is less than -62,135,596,800,000.</para>
/// -or-
/// <para><paramref name="value" /> is greater than 253,402,300,799,999.</para>
/// </exception>
public static DateTimeOffset FromUnixTimeMilliseconds(this int value)
{
return DateTimeOffset.FromUnixTimeMilliseconds(value);
}
/// <summary>
/// Converts a Unix time expressed as the number of seconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value.
/// </summary>
/// <param name="value">
/// A Unix time, expressed as the number of seconds that have elapsed since 1970-01-01T00:00:00Z (January 1, 1970, at
/// 12:00 AM UTC). For Unix times before this date, its value is negative.
/// </param>
/// <returns>A date and time value that represents the same moment in time as the Unix time.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <para><paramref name="value" /> is less than -62,135,596,800.</para>
/// -or-
/// <para><paramref name="value" /> is greater than 253,402,300,799.</para>
/// </exception>
public static DateTimeOffset FromUnixTimeSeconds(this int value)
{
return DateTimeOffset.FromUnixTimeSeconds(value);
}
/// <summary>
/// Returns a <see cref="TimeSpan" /> that represents this value as the number of ticks.
/// </summary>

View File

@ -5,6 +5,44 @@
/// </summary>
public static class Int64Extensions
{
/// <summary>
/// Converts a Unix time expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value.
/// </summary>
/// <param name="value">
/// A Unix time, expressed as the number of milliseconds that have elapsed since 1970-01-01T00:00:00Z (January 1,
/// 1970, at 12:00 AM UTC). For Unix times before this date, its value is negative.
/// </param>
/// <returns>A date and time value that represents the same moment in time as the Unix time.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <para><paramref name="value" /> is less than -62,135,596,800,000.</para>
/// -or-
/// <para><paramref name="value" /> is greater than 253,402,300,799,999.</para>
/// </exception>
public static DateTimeOffset FromUnixTimeMilliseconds(this long value)
{
return DateTimeOffset.FromUnixTimeMilliseconds(value);
}
/// <summary>
/// Converts a Unix time expressed as the number of seconds that have elapsed since 1970-01-01T00:00:00Z to a
/// <see cref="DateTimeOffset" /> value.
/// </summary>
/// <param name="value">
/// A Unix time, expressed as the number of seconds that have elapsed since 1970-01-01T00:00:00Z (January 1, 1970, at
/// 12:00 AM UTC). For Unix times before this date, its value is negative.
/// </param>
/// <returns>A date and time value that represents the same moment in time as the Unix time.</returns>
/// <exception cref="ArgumentOutOfRangeException">
/// <para><paramref name="value" /> is less than -62,135,596,800.</para>
/// -or-
/// <para><paramref name="value" /> is greater than 253,402,300,799.</para>
/// </exception>
public static DateTimeOffset FromUnixTimeSeconds(this long value)
{
return DateTimeOffset.FromUnixTimeSeconds(value);
}
/// <summary>
/// Returns a <see cref="TimeSpan" /> that represents this value as the number of ticks.
/// </summary>