diff --git a/X10D.Tests/src/IO/UInt16Tests.cs b/X10D.Tests/src/IO/UInt16Tests.cs
index 465a1e0..be9360e 100644
--- a/X10D.Tests/src/IO/UInt16Tests.cs
+++ b/X10D.Tests/src/IO/UInt16Tests.cs
@@ -1,4 +1,4 @@
-using NUnit.Framework;
+using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
diff --git a/X10D.Tests/src/IO/UInt32Tests.cs b/X10D.Tests/src/IO/UInt32Tests.cs
index cb0f17b..7847759 100644
--- a/X10D.Tests/src/IO/UInt32Tests.cs
+++ b/X10D.Tests/src/IO/UInt32Tests.cs
@@ -1,4 +1,4 @@
-using NUnit.Framework;
+using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
diff --git a/X10D.Tests/src/IO/UInt64Tests.cs b/X10D.Tests/src/IO/UInt64Tests.cs
index dfaa621..e783e2a 100644
--- a/X10D.Tests/src/IO/UInt64Tests.cs
+++ b/X10D.Tests/src/IO/UInt64Tests.cs
@@ -1,4 +1,4 @@
-using NUnit.Framework;
+using NUnit.Framework;
using X10D.IO;
namespace X10D.Tests.IO;
diff --git a/X10D.Tests/src/Math/ByteTests.cs b/X10D.Tests/src/Math/ByteTests.cs
index 6608222..ac1b99e 100644
--- a/X10D.Tests/src/Math/ByteTests.cs
+++ b/X10D.Tests/src/Math/ByteTests.cs
@@ -51,13 +51,29 @@ internal partial class ByteTests
}
[Test]
- public void DigitalRootShouldBeCorrect()
+ public void DigitalRoot_ShouldReturn4_Given238()
{
const byte value = 238;
Assert.That(value.DigitalRoot(), Is.EqualTo(4));
Assert.That((-value).DigitalRoot(), Is.EqualTo(4));
}
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given9()
+ {
+ const byte value = 9;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(9));
+ }
+
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given18()
+ {
+ const byte value = 18;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(9));
+ }
+
[Test]
public void FactorialShouldBeCorrect()
{
diff --git a/X10D.Tests/src/Math/Int16Tests.cs b/X10D.Tests/src/Math/Int16Tests.cs
index 7ba50a2..ac68889 100644
--- a/X10D.Tests/src/Math/Int16Tests.cs
+++ b/X10D.Tests/src/Math/Int16Tests.cs
@@ -62,13 +62,29 @@ internal partial class Int16Tests
}
[Test]
- public void DigitalRootShouldBeCorrect()
+ public void DigitalRoot_ShouldReturn4_Given238()
{
const short value = 238;
Assert.That(value.DigitalRoot(), Is.EqualTo(4));
Assert.That((-value).DigitalRoot(), Is.EqualTo(4));
}
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given9()
+ {
+ const short value = 9;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(9));
+ }
+
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given18()
+ {
+ const short value = 18;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(9));
+ }
+
[Test]
public void FactorialShouldBeCorrect()
{
diff --git a/X10D.Tests/src/Math/Int32Tests.cs b/X10D.Tests/src/Math/Int32Tests.cs
index 664e16f..68e05cd 100644
--- a/X10D.Tests/src/Math/Int32Tests.cs
+++ b/X10D.Tests/src/Math/Int32Tests.cs
@@ -62,13 +62,29 @@ internal partial class Int32Tests
}
[Test]
- public void DigitalRootShouldBeCorrect()
+ public void DigitalRoot_ShouldReturn4_Given238()
{
const int value = 238;
Assert.That(value.DigitalRoot(), Is.EqualTo(4));
Assert.That((-value).DigitalRoot(), Is.EqualTo(4));
}
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given9()
+ {
+ const int value = 9;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(9));
+ }
+
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given18()
+ {
+ const int value = 18;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(9));
+ }
+
[Test]
public void FactorialShouldBeCorrect()
{
diff --git a/X10D.Tests/src/Math/Int64Tests.cs b/X10D.Tests/src/Math/Int64Tests.cs
index 8dd40a9..e1f37fd 100644
--- a/X10D.Tests/src/Math/Int64Tests.cs
+++ b/X10D.Tests/src/Math/Int64Tests.cs
@@ -62,13 +62,29 @@ internal partial class Int64Tests
}
[Test]
- public void DigitalRootShouldBeCorrect()
+ public void DigitalRoot_ShouldReturn4_Given238()
{
const long value = 238;
Assert.That(value.DigitalRoot(), Is.EqualTo(4));
Assert.That((-value).DigitalRoot(), Is.EqualTo(4));
}
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given9()
+ {
+ const long value = 9;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(9));
+ }
+
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given18()
+ {
+ const long value = 18;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(9));
+ }
+
[Test]
public void FactorialShouldBeCorrect()
{
diff --git a/X10D.Tests/src/Math/SByteTests.cs b/X10D.Tests/src/Math/SByteTests.cs
index 3727af4..fd9a4fa 100644
--- a/X10D.Tests/src/Math/SByteTests.cs
+++ b/X10D.Tests/src/Math/SByteTests.cs
@@ -62,13 +62,29 @@ internal partial class SByteTests
}
[Test]
- public void DigitalRootShouldBeCorrect()
+ public void DigitalRoot_ShouldReturn4_Given127()
{
const sbyte value = 127; // sbyte.MaxValue. can't use 238 like the other tests
Assert.That(value.DigitalRoot(), Is.EqualTo(1));
Assert.That((-value).DigitalRoot(), Is.EqualTo(1));
}
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given9()
+ {
+ const sbyte value = 9;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(9));
+ }
+
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given18()
+ {
+ const sbyte value = 18;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(9));
+ }
+
[Test]
public void FactorialShouldBeCorrect()
{
diff --git a/X10D.Tests/src/Math/UInt16Tests.cs b/X10D.Tests/src/Math/UInt16Tests.cs
index d51f983..3a7bb0d 100644
--- a/X10D.Tests/src/Math/UInt16Tests.cs
+++ b/X10D.Tests/src/Math/UInt16Tests.cs
@@ -51,13 +51,29 @@ internal partial class UInt16Tests
}
[Test]
- public void DigitalRootShouldBeCorrect()
+ public void DigitalRoot_ShouldReturn4_Given238()
{
const ushort value = 238;
Assert.That(value.DigitalRoot(), Is.EqualTo(4));
Assert.That((-value).DigitalRoot(), Is.EqualTo(4));
}
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given9()
+ {
+ const ushort value = 9;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(9));
+ }
+
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given18()
+ {
+ const ushort value = 18;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(9));
+ }
+
[Test]
public void FactorialShouldBeCorrect()
{
diff --git a/X10D.Tests/src/Math/UInt32Tests.cs b/X10D.Tests/src/Math/UInt32Tests.cs
index 5c161ff..e5c9e91 100644
--- a/X10D.Tests/src/Math/UInt32Tests.cs
+++ b/X10D.Tests/src/Math/UInt32Tests.cs
@@ -1,4 +1,4 @@
-using NUnit.Framework;
+using NUnit.Framework;
using X10D.Math;
namespace X10D.Tests.Math;
@@ -50,11 +50,27 @@ internal partial class UInt32Tests
}
[Test]
- public void DigitalRootShouldBeCorrect()
+ public void DigitalRoot_ShouldReturn4_Given238()
{
const uint value = 238;
- Assert.That(value.DigitalRoot(), Is.EqualTo(4U));
- Assert.That((-value).DigitalRoot(), Is.EqualTo(4U));
+ Assert.That(value.DigitalRoot(), Is.EqualTo(4));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(4));
+ }
+
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given9()
+ {
+ const uint value = 9;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(9));
+ }
+
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given18()
+ {
+ const uint value = 18;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-value).DigitalRoot(), Is.EqualTo(9));
}
[Test]
diff --git a/X10D.Tests/src/Math/UInt64Tests.cs b/X10D.Tests/src/Math/UInt64Tests.cs
index 909548f..8c7a215 100644
--- a/X10D.Tests/src/Math/UInt64Tests.cs
+++ b/X10D.Tests/src/Math/UInt64Tests.cs
@@ -1,4 +1,4 @@
-using NUnit.Framework;
+using NUnit.Framework;
using X10D.Math;
namespace X10D.Tests.Math;
@@ -51,15 +51,31 @@ internal partial class UInt64Tests
}
[Test]
- public void DigitalRootShouldBeCorrect()
+ public void DigitalRoot_ShouldReturn4_Given238()
{
const ulong value = 238;
- Assert.That(value.DigitalRoot(), Is.EqualTo(4U));
+ Assert.That(value.DigitalRoot(), Is.EqualTo(4));
// -ulong operator not defined because it might exceed long.MinValue,
// so instead, cast to long and then negate.
// HAX.
- Assert.That((-(long)value).DigitalRoot(), Is.EqualTo(4U));
+ Assert.That((-(long)value).DigitalRoot(), Is.EqualTo(4));
+ }
+
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given9()
+ {
+ const ulong value = 9;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-(long)value).DigitalRoot(), Is.EqualTo(9));
+ }
+
+ [Test]
+ public void DigitalRoot_ShouldReturn9_Given18()
+ {
+ const ulong value = 18;
+ Assert.That(value.DigitalRoot(), Is.EqualTo(9));
+ Assert.That((-(long)value).DigitalRoot(), Is.EqualTo(9));
}
[Test]
diff --git a/X10D.Tests/src/Numerics/NumberTests.cs b/X10D.Tests/src/Numerics/NumberTests.cs
new file mode 100644
index 0000000..f5b5127
--- /dev/null
+++ b/X10D.Tests/src/Numerics/NumberTests.cs
@@ -0,0 +1,32 @@
+#if NET7_0_OR_GREATER
+using NUnit.Framework;
+using X10D.Math;
+
+namespace X10D.Tests.Numerics;
+
+[TestFixture]
+internal class NumberTests
+{
+ [Test]
+ public void Sign_ShouldReturn1_GivenPositiveNumber()
+ {
+ Assert.That(NumberExtensions.Sign(2), Is.Positive);
+ Assert.That(NumberExtensions.Sign(2), Is.EqualTo(1));
+ }
+
+ [Test]
+ public void Sign_Should0_GivenZero()
+ {
+ Assert.That(NumberExtensions.Sign(0), Is.Not.Positive);
+ Assert.That(NumberExtensions.Sign(0), Is.Not.Negative);
+ Assert.That(NumberExtensions.Sign(0), Is.EqualTo(0));
+ }
+
+ [Test]
+ public void Sign_ShouldReturnNegative1_GivenNegativeNumber()
+ {
+ Assert.That(NumberExtensions.Sign(-2), Is.Negative);
+ Assert.That(NumberExtensions.Sign(-2), Is.EqualTo(-1));
+ }
+}
+#endif
diff --git a/X10D/src/Collections/BinaryIntegerExtensions.cs b/X10D/src/Collections/BinaryIntegerExtensions.cs
new file mode 100644
index 0000000..0aec0d0
--- /dev/null
+++ b/X10D/src/Collections/BinaryIntegerExtensions.cs
@@ -0,0 +1,98 @@
+#if NET7_0_OR_GREATER
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Numerics;
+using System.Runtime.CompilerServices;
+using System.Runtime.Intrinsics.X86;
+using X10D.CompilerServices;
+
+namespace X10D.Collections;
+
+///
+/// Collection-related extension methods for .
+///
+public static class BinaryIntegerExtensions
+{
+ ///
+ /// Unpacks this integer into a boolean list, treating it as a bit field.
+ ///
+ /// The value to unpack.
+ /// An array of with a length equal to the size of .
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static bool[] Unpack(this TInteger value)
+ where TInteger : unmanaged, IBinaryInteger
+ {
+ unsafe
+ {
+ var buffer = new bool[sizeof(TInteger) * 8];
+ value.Unpack(buffer);
+ return buffer;
+ }
+ }
+
+ ///
+ /// Unpacks this integer into a boolean list, treating it as a bit field.
+ ///
+ /// The value to unpack.
+ /// When this method returns, contains the unpacked booleans from .
+ /// is not large enough to contain the result.
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static void Unpack(this TInteger value, Span destination)
+ where TInteger : unmanaged, IBinaryInteger
+ {
+ unsafe
+ {
+ if (destination.Length < sizeof(TInteger) * 8)
+ {
+ throw new ArgumentException(ExceptionMessages.DestinationSpanLengthTooShort, nameof(destination));
+ }
+ }
+
+ UnpackInternal(value, destination);
+ }
+
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ private static void UnpackInternal_Fallback(this TInteger value, Span destination)
+ where TInteger : unmanaged, IBinaryInteger
+ {
+ unsafe
+ {
+ int bitCount = sizeof(TInteger) * 8;
+ for (var index = 0; index < bitCount; index++)
+ {
+ destination[index] = (value & (TInteger.One << index)) != TInteger.Zero;
+ }
+ }
+ }
+
+ [ExcludeFromCodeCoverage]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ private static void UnpackInternal(TInteger value, Span destination)
+ where TInteger : unmanaged, IBinaryInteger
+ {
+ switch (value)
+ {
+ case byte valueByte when Sse3.IsSupported:
+ valueByte.UnpackInternal_Ssse3(destination);
+ break;
+
+ case int valueInt32 when Avx2.IsSupported:
+ valueInt32.UnpackInternal_Ssse3(destination);
+ break;
+
+ case int valueInt32 when Sse3.IsSupported:
+ valueInt32.UnpackInternal_Ssse3(destination);
+ break;
+
+ case short valueInt16 when Sse3.IsSupported:
+ valueInt16.UnpackInternal_Ssse3(destination);
+ break;
+
+ default:
+ UnpackInternal_Fallback(value, destination);
+ break;
+ }
+ }
+}
+#endif
diff --git a/X10D/src/Collections/ByteExtensions.cs b/X10D/src/Collections/ByteExtensions.cs
index 5207b26..bdcdcce 100644
--- a/X10D/src/Collections/ByteExtensions.cs
+++ b/X10D/src/Collections/ByteExtensions.cs
@@ -1,5 +1,7 @@
+#if !NET7_0_OR_GREATER
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
+#endif
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
@@ -14,6 +16,7 @@ public static class ByteExtensions
{
private const int Size = sizeof(byte) * 8;
+#if !NET7_0_OR_GREATER
///
/// Unpacks this 8-bit unsigned integer into a boolean list, treating it as a bit field.
///
@@ -51,6 +54,7 @@ public static class ByteExtensions
UnpackInternal_Fallback(value, destination);
}
+#endif
[MethodImpl(CompilerResources.MaxOptimization)]
internal static void UnpackInternal_Fallback(this byte value, Span destination)
diff --git a/X10D/src/Collections/Int16Extensions.cs b/X10D/src/Collections/Int16Extensions.cs
index fb722b9..e3e5570 100644
--- a/X10D/src/Collections/Int16Extensions.cs
+++ b/X10D/src/Collections/Int16Extensions.cs
@@ -1,5 +1,7 @@
+#if !NET7_0_OR_GREATER
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
+#endif
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
@@ -14,6 +16,7 @@ public static class Int16Extensions
{
private const int Size = sizeof(short) * 8;
+#if !NET7_0_OR_GREATER
///
/// Unpacks this 16-bit signed integer into a boolean list, treating it as a bit field.
///
@@ -51,6 +54,7 @@ public static class Int16Extensions
UnpackInternal_Fallback(value, destination);
}
+#endif
[MethodImpl(CompilerResources.MaxOptimization)]
internal static void UnpackInternal_Fallback(this short value, Span destination)
diff --git a/X10D/src/Collections/Int32Extensions.cs b/X10D/src/Collections/Int32Extensions.cs
index 19dbe7e..b74a311 100644
--- a/X10D/src/Collections/Int32Extensions.cs
+++ b/X10D/src/Collections/Int32Extensions.cs
@@ -1,5 +1,7 @@
+#if !NET7_0_OR_GREATER
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Contracts;
+#endif
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
@@ -14,6 +16,7 @@ public static class Int32Extensions
{
private const int Size = sizeof(int) * 8;
+#if !NET7_0_OR_GREATER
///
/// Unpacks this 32-bit signed integer into a boolean list, treating it as a bit field.
///
@@ -57,6 +60,7 @@ public static class Int32Extensions
UnpackInternal_Fallback(value, destination);
}
+#endif
[MethodImpl(CompilerResources.MaxOptimization)]
internal static void UnpackInternal_Fallback(this int value, Span destination)
diff --git a/X10D/src/Collections/Int64Extensions.cs b/X10D/src/Collections/Int64Extensions.cs
index 505f3da..c72dfbd 100644
--- a/X10D/src/Collections/Int64Extensions.cs
+++ b/X10D/src/Collections/Int64Extensions.cs
@@ -1,3 +1,4 @@
+#if !NET7_0_OR_GREATER
using System.Diagnostics.Contracts;
namespace X10D.Collections;
@@ -41,3 +42,4 @@ public static class Int64Extensions
}
}
}
+#endif
diff --git a/X10D/src/IO/DoubleExtensions.cs b/X10D/src/IO/DoubleExtensions.cs
index c190e45..8856c79 100644
--- a/X10D/src/IO/DoubleExtensions.cs
+++ b/X10D/src/IO/DoubleExtensions.cs
@@ -1,4 +1,4 @@
-using System.Buffers.Binary;
+using System.Buffers.Binary;
using System.Diagnostics.Contracts;
using System.Runtime.InteropServices;
diff --git a/X10D/src/IO/Int16Extensions.cs b/X10D/src/IO/Int16Extensions.cs
index f5840e2..af81b2d 100644
--- a/X10D/src/IO/Int16Extensions.cs
+++ b/X10D/src/IO/Int16Extensions.cs
@@ -1,4 +1,4 @@
-using System.Buffers.Binary;
+using System.Buffers.Binary;
using System.Diagnostics.Contracts;
namespace X10D.IO;
diff --git a/X10D/src/IO/Int32Extensions.cs b/X10D/src/IO/Int32Extensions.cs
index 76449f8..0556ab6 100644
--- a/X10D/src/IO/Int32Extensions.cs
+++ b/X10D/src/IO/Int32Extensions.cs
@@ -1,4 +1,4 @@
-using System.Buffers.Binary;
+using System.Buffers.Binary;
using System.Diagnostics.Contracts;
namespace X10D.IO;
diff --git a/X10D/src/IO/Int64Extensions.cs b/X10D/src/IO/Int64Extensions.cs
index 133f86a..447c794 100644
--- a/X10D/src/IO/Int64Extensions.cs
+++ b/X10D/src/IO/Int64Extensions.cs
@@ -1,4 +1,4 @@
-using System.Buffers.Binary;
+using System.Buffers.Binary;
using System.Diagnostics.Contracts;
namespace X10D.IO;
diff --git a/X10D/src/IO/SingleExtensions.cs b/X10D/src/IO/SingleExtensions.cs
index efdb17b..6e65001 100644
--- a/X10D/src/IO/SingleExtensions.cs
+++ b/X10D/src/IO/SingleExtensions.cs
@@ -1,4 +1,4 @@
-using System.Buffers.Binary;
+using System.Buffers.Binary;
using System.Diagnostics.Contracts;
#if !NET5_0_OR_GREATER
using System.Runtime.InteropServices;
diff --git a/X10D/src/IO/UInt16Extensions.cs b/X10D/src/IO/UInt16Extensions.cs
index a977277..972281a 100644
--- a/X10D/src/IO/UInt16Extensions.cs
+++ b/X10D/src/IO/UInt16Extensions.cs
@@ -1,4 +1,4 @@
-using System.Buffers.Binary;
+using System.Buffers.Binary;
using System.Diagnostics.Contracts;
namespace X10D.IO;
diff --git a/X10D/src/IO/UInt32Extensions.cs b/X10D/src/IO/UInt32Extensions.cs
index 7865ff5..099a87d 100644
--- a/X10D/src/IO/UInt32Extensions.cs
+++ b/X10D/src/IO/UInt32Extensions.cs
@@ -1,4 +1,4 @@
-using System.Buffers.Binary;
+using System.Buffers.Binary;
using System.Diagnostics.Contracts;
namespace X10D.IO;
diff --git a/X10D/src/IO/UInt64Extensions.cs b/X10D/src/IO/UInt64Extensions.cs
index a6adf1c..bd9305c 100644
--- a/X10D/src/IO/UInt64Extensions.cs
+++ b/X10D/src/IO/UInt64Extensions.cs
@@ -1,4 +1,4 @@
-using System.Buffers.Binary;
+using System.Buffers.Binary;
using System.Diagnostics.Contracts;
namespace X10D.IO;
diff --git a/X10D/src/Math/BigIntegerExtensions.cs b/X10D/src/Math/BigIntegerExtensions.cs
index b2ab805..79c936c 100644
--- a/X10D/src/Math/BigIntegerExtensions.cs
+++ b/X10D/src/Math/BigIntegerExtensions.cs
@@ -10,6 +10,7 @@ namespace X10D.Math;
///
public static class BigIntegerExtensions
{
+#if !NET7_0_OR_GREATER
///
/// Returns the number of digits in the current integer.
///
@@ -42,6 +43,7 @@ public static class BigIntegerExtensions
BigInteger root = BigInteger.Abs(value).Mod(9);
return (int)(root == 0 ? 9 : root);
}
+#endif
///
/// Returns the factorial of the current 64-bit signed integer.
@@ -170,6 +172,7 @@ public static class BigIntegerExtensions
return value * other / value.GreatestCommonFactor(other);
}
+#if !NET7_0_OR_GREATER
///
/// Performs a modulo operation which supports a negative dividend.
///
@@ -191,6 +194,7 @@ public static class BigIntegerExtensions
BigInteger r = dividend % divisor;
return r < 0 ? r + divisor : r;
}
+#endif
///
/// Returns the multiplicative persistence of a specified value.
diff --git a/X10D/src/Math/BinaryIntegerExtensions.cs b/X10D/src/Math/BinaryIntegerExtensions.cs
new file mode 100644
index 0000000..ce10a7e
--- /dev/null
+++ b/X10D/src/Math/BinaryIntegerExtensions.cs
@@ -0,0 +1,101 @@
+#if NET7_0_OR_GREATER
+using System.Diagnostics.Contracts;
+using System.Numerics;
+using System.Runtime.CompilerServices;
+using X10D.CompilerServices;
+
+namespace X10D.Math;
+
+///
+/// Math-related extension methods for .
+///
+public static class BinaryIntegerExtensions
+{
+ ///
+ /// Returns the number of digits in the current binary integer.
+ ///
+ /// The value whose digit count to compute.
+ /// The number of digits in .
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static int CountDigits(this TInteger value)
+ where TInteger : IBinaryInteger
+ {
+ if (TInteger.IsZero(value))
+ {
+ return 1;
+ }
+
+ return 1 + (int)System.Math.Floor(System.Math.Log10(System.Math.Abs(double.CreateChecked(value))));
+ }
+
+ ///
+ /// Computes the digital root of this integer.
+ ///
+ /// The value whose digital root to compute.
+ /// The digital root of .
+ /// The digital root is defined as the recursive sum of digits until that result is a single digit.
+ ///
+ /// The digital root is defined as the recursive sum of digits until that result is a single digit.
+ /// For example, the digital root of 239 is 5: 2 + 3 + 9 = 14, then 1 + 4 = 5.
+ ///
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static int DigitalRoot(this TInteger value)
+ where TInteger : IBinaryInteger
+ {
+ var nine = TInteger.CreateChecked(9);
+ TInteger root = TInteger.Abs(value).Mod(nine);
+ return int.CreateChecked(root == TInteger.Zero ? nine : root);
+ }
+
+ ///
+ /// Returns the factorial of the current binary integer.
+ ///
+ /// The value whose factorial to compute.
+ /// The factorial of .
+ /// is less than 0.
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static long Factorial(this TInteger value)
+ where TInteger : IBinaryInteger
+ {
+ if (value < TInteger.Zero)
+ {
+ throw new ArithmeticException(nameof(value));
+ }
+
+ if (value == TInteger.Zero)
+ {
+ return 1;
+ }
+
+ var result = 1L;
+ for (TInteger i = TInteger.One; i <= value; i++)
+ {
+ result *= long.CreateChecked(i);
+ }
+
+ return result;
+ }
+
+ ///
+ /// Calculates the greatest common factor between the current binary integer, and another binary integer.
+ ///
+ /// The first value.
+ /// The second value.
+ /// The greatest common factor between and .
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static TInteger GreatestCommonFactor(this TInteger value, TInteger other)
+ where TInteger : IBinaryInteger
+ {
+ while (other != TInteger.Zero)
+ {
+ (value, other) = (other, value % other);
+ }
+
+ return value;
+ }
+}
+#endif
diff --git a/X10D/src/Math/ByteExtensions.cs b/X10D/src/Math/ByteExtensions.cs
index 95d1188..0bd8486 100644
--- a/X10D/src/Math/ByteExtensions.cs
+++ b/X10D/src/Math/ByteExtensions.cs
@@ -9,6 +9,7 @@ namespace X10D.Math;
///
public static class ByteExtensions
{
+#if !NET7_0_OR_GREATER
///
/// Returns the number of digits in the current 8-bit unsigned integer.
///
@@ -107,6 +108,7 @@ public static class ByteExtensions
{
return !value.IsEven();
}
+#endif
///
/// Returns a value indicating whether the current value is a prime number.
diff --git a/X10D/src/Math/Int16Extensions.cs b/X10D/src/Math/Int16Extensions.cs
index aa9fa9b..318a948 100644
--- a/X10D/src/Math/Int16Extensions.cs
+++ b/X10D/src/Math/Int16Extensions.cs
@@ -9,6 +9,7 @@ namespace X10D.Math;
///
public static class Int16Extensions
{
+#if !NET7_0_OR_GREATER
///
/// Returns the number of digits in the current 16-bit signed integer.
///
@@ -112,6 +113,7 @@ public static class Int16Extensions
{
return !value.IsEven();
}
+#endif
///
/// Returns a value indicating whether the current value is a prime number.
@@ -140,6 +142,7 @@ public static class Int16Extensions
return (short)((long)value).LowestCommonMultiple(other);
}
+#if !NET7_0_OR_GREATER
///
/// Performs a modulo operation which supports a negative dividend.
///
@@ -161,6 +164,7 @@ public static class Int16Extensions
int r = dividend % divisor;
return (short)(r < 0 ? r + divisor : r);
}
+#endif
///
/// Returns the multiplicative persistence of a specified value.
diff --git a/X10D/src/Math/Int32Extensions.cs b/X10D/src/Math/Int32Extensions.cs
index 4d91fcd..e0b05cc 100644
--- a/X10D/src/Math/Int32Extensions.cs
+++ b/X10D/src/Math/Int32Extensions.cs
@@ -9,6 +9,7 @@ namespace X10D.Math;
///
public static class Int32Extensions
{
+#if !NET7_0_OR_GREATER
///
/// Returns the number of digits in the current 32-bit signed integer.
///
@@ -112,6 +113,7 @@ public static class Int32Extensions
{
return !value.IsEven();
}
+#endif
///
/// Returns a value indicating whether the current value is a prime number.
@@ -140,6 +142,7 @@ public static class Int32Extensions
return (int)((long)value).LowestCommonMultiple(other);
}
+#if !NET7_0_OR_GREATER
///
/// Performs a modulo operation which supports a negative dividend.
///
@@ -161,6 +164,7 @@ public static class Int32Extensions
int r = dividend % divisor;
return r < 0 ? r + divisor : r;
}
+#endif
///
/// Returns the multiplicative persistence of a specified value.
diff --git a/X10D/src/Math/Int64Extensions.cs b/X10D/src/Math/Int64Extensions.cs
index 0c6a530..b0c1e58 100644
--- a/X10D/src/Math/Int64Extensions.cs
+++ b/X10D/src/Math/Int64Extensions.cs
@@ -9,6 +9,7 @@ namespace X10D.Math;
///
public static class Int64Extensions
{
+#if !NET7_0_OR_GREATER
///
/// Returns the number of digits in the current 64-bit signed integer.
///
@@ -117,6 +118,7 @@ public static class Int64Extensions
{
return !value.IsEven();
}
+#endif
///
/// Returns a value indicating whether the current value is a prime number.
@@ -179,6 +181,7 @@ public static class Int64Extensions
return value * other / value.GreatestCommonFactor(other);
}
+#if !NET7_0_OR_GREATER
///
/// Performs a modulo operation which supports a negative dividend.
///
@@ -200,6 +203,7 @@ public static class Int64Extensions
long r = dividend % divisor;
return r < 0 ? r + divisor : r;
}
+#endif
///
/// Returns the multiplicative persistence of a specified value.
diff --git a/X10D/src/Math/MathUtility.cs b/X10D/src/Math/MathUtility.cs
index 59601ce..0ca9365 100644
--- a/X10D/src/Math/MathUtility.cs
+++ b/X10D/src/Math/MathUtility.cs
@@ -1,4 +1,5 @@
using System.Diagnostics.Contracts;
+using System.Numerics;
using System.Runtime.CompilerServices;
using X10D.CompilerServices;
@@ -12,34 +13,6 @@ public static class MathUtility
private const double DefaultGamma = 2.2;
private const float DefaultGammaF = 2.2f;
- ///
- /// Applies a simple bias function to value.
- ///
- /// The value to which the bias function will be applied.
- /// The bias value. Valid values range from 0-1.
- /// The biased result.
- ///
- /// If is less than 0.5, will be shifted downward; otherwise, upward.
- ///
- public static float Bias(float value, float bias)
- {
- return value / ((1.0f / bias - 2.0f) * (1.0f - value) + 1.0f);
- }
-
- ///
- /// Applies a simple bias function to value.
- ///
- /// The value to which the bias function will be applied.
- /// The bias value. Valid values range from 0-1.
- /// The biased result.
- ///
- /// If is less than 0.5, will be shifted downward; otherwise, upward.
- ///
- public static double Bias(double value, double bias)
- {
- return value / ((1.0 / bias - 2.0) * (1.0 - value) + 1.0);
- }
-
///
/// Calculates exponential decay for a value.
///
@@ -154,6 +127,35 @@ public static class MathUtility
return (alpha - start) / (end - start);
}
+#if !NET7_0_OR_GREATER
+ ///
+ /// Applies a simple bias function to value.
+ ///
+ /// The value to which the bias function will be applied.
+ /// The bias value. Valid values range from 0-1.
+ /// The biased result.
+ ///
+ /// If is less than 0.5, will be shifted downward; otherwise, upward.
+ ///
+ public static float Bias(float value, float bias)
+ {
+ return value / ((1.0f / bias - 2.0f) * (1.0f - value) + 1.0f);
+ }
+
+ ///
+ /// Applies a simple bias function to value.
+ ///
+ /// The value to which the bias function will be applied.
+ /// The bias value. Valid values range from 0-1.
+ /// The biased result.
+ ///
+ /// If is less than 0.5, will be shifted downward; otherwise, upward.
+ ///
+ public static double Bias(double value, double bias)
+ {
+ return value / ((1.0 / bias - 2.0) * (1.0 - value) + 1.0);
+ }
+
///
/// Linearly interpolates from one value to a target using a specified alpha.
///
@@ -190,6 +192,93 @@ public static class MathUtility
return ((1.0 - alpha) * value) + (alpha * target);
}
+ ///
+ /// Performs smooth Hermite interpolation from one value to a target using a specified alpha.
+ ///
+ /// The interpolation source.
+ /// The interpolation target.
+ /// The interpolation alpha.
+ /// The interpolation result.
+ public static float SmoothStep(float value, float target, float alpha)
+ {
+ alpha = System.Math.Clamp(alpha, 0.0f, 1.0f);
+ alpha = -2.0f * alpha * alpha * alpha + 3.0f * alpha * alpha;
+ return target * alpha + value * (1.0f - alpha);
+ }
+
+ ///
+ /// Performs smooth Hermite interpolation from one value to a target using a specified alpha.
+ ///
+ /// The interpolation source.
+ /// The interpolation target.
+ /// The interpolation alpha.
+ /// The interpolation result.
+ public static double SmoothStep(double value, double target, double alpha)
+ {
+ alpha = System.Math.Clamp(alpha, 0.0, 1.0);
+ alpha = -2.0 * alpha * alpha * alpha + 3.0 * alpha * alpha;
+ return target * alpha + value * (1.0 - alpha);
+ }
+
+ ///
+ /// Converts a value from being a percentage of one range, to being the same percentage in a new range.
+ ///
+ /// The value to convert.
+ /// The old minimum value.
+ /// The old maximum value.
+ /// The new minimum value.
+ /// The new maximum value.
+ /// The scaled value.
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static float ScaleRange(float value, float oldMin, float oldMax, float newMin, float newMax)
+ {
+ float oldRange = oldMax - oldMin;
+ float newRange = newMax - newMin;
+ float alpha = (value - oldMin) / oldRange;
+ return (alpha * newRange) + newMin;
+ }
+
+ ///
+ /// Converts a value from being a percentage of one range, to being the same percentage in a new range.
+ ///
+ /// The value to convert.
+ /// The old minimum value.
+ /// The old maximum value.
+ /// The new minimum value.
+ /// The new maximum value.
+ /// The scaled value.
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static double ScaleRange(double value, double oldMin, double oldMax, double newMin, double newMax)
+ {
+ double oldRange = oldMax - oldMin;
+ double newRange = newMax - newMin;
+ double alpha = (value - oldMin) / oldRange;
+ return (alpha * newRange) + newMin;
+ }
+
+ ///
+ /// Returns the incremental sawtooth wave of a given value.
+ ///
+ /// The value to calculate.
+ /// The sawtooth wave of the given value.
+ public static float Sawtooth(float value)
+ {
+ return (value - MathF.Floor(value));
+ }
+
+ ///
+ /// Returns the incremental sawtooth wave of a given value.
+ ///
+ /// The value to calculate.
+ /// The sawtooth wave of the given value.
+ public static double Sawtooth(double value)
+ {
+ return (value - System.Math.Floor(value));
+ }
+#endif
+
///
/// Converts a linear value to a gamma-encoded value using a gamma value of 2.2.
///
@@ -272,64 +361,6 @@ public static class MathUtility
return Unsafe.As(ref result);
}
- ///
- /// Returns the incremental sawtooth wave of a given value.
- ///
- /// The value to calculate.
- /// The sawtooth wave of the given value.
- public static float Sawtooth(float value)
- {
- return (value - MathF.Floor(value));
- }
-
- ///
- /// Returns the incremental sawtooth wave of a given value.
- ///
- /// The value to calculate.
- /// The sawtooth wave of the given value.
- public static double Sawtooth(double value)
- {
- return (value - System.Math.Floor(value));
- }
-
- ///
- /// Converts a value from being a percentage of one range, to being the same percentage in a new range.
- ///
- /// The value to convert.
- /// The old minimum value.
- /// The old maximum value.
- /// The new minimum value.
- /// The new maximum value.
- /// The scaled value.
- [Pure]
- [MethodImpl(CompilerResources.MaxOptimization)]
- public static float ScaleRange(float value, float oldMin, float oldMax, float newMin, float newMax)
- {
- float oldRange = oldMax - oldMin;
- float newRange = newMax - newMin;
- float alpha = (value - oldMin) / oldRange;
- return (alpha * newRange) + newMin;
- }
-
- ///
- /// Converts a value from being a percentage of one range, to being the same percentage in a new range.
- ///
- /// The value to convert.
- /// The old minimum value.
- /// The old maximum value.
- /// The new minimum value.
- /// The new maximum value.
- /// The scaled value.
- [Pure]
- [MethodImpl(CompilerResources.MaxOptimization)]
- public static double ScaleRange(double value, double oldMin, double oldMax, double newMin, double newMax)
- {
- double oldRange = oldMax - oldMin;
- double newRange = newMax - newMin;
- double alpha = (value - oldMin) / oldRange;
- return (alpha * newRange) + newMin;
- }
-
///
/// Calculates the sigmoid function for the given input value.
///
@@ -358,18 +389,71 @@ public static class MathUtility
return 1.0f / (1.0f + System.Math.Exp(-value));
}
+#if NET7_0_OR_GREATER
///
- /// Performs smooth Hermite interpolation from one value to a target using a specified alpha.
+ /// Applies a simple bias function to value.
+ ///
+ /// The value to which the bias function will be applied.
+ /// The bias value. Valid values range from 0-1.
+ /// The biased result.
+ ///
+ /// If is less than 0.5, will be shifted downward; otherwise, upward.
+ ///
+ public static TNumber Bias(TNumber value, TNumber bias)
+ where TNumber : INumber
+ {
+ TNumber identity = TNumber.MultiplicativeIdentity;
+ return value / ((identity / bias - TNumber.CreateChecked(2)) * (identity - value) + identity);
+ }
+
+ ///
+ /// Linearly interpolates from one value to a target using a specified alpha.
///
/// The interpolation source.
/// The interpolation target.
/// The interpolation alpha.
- /// The interpolation result.
- public static float SmoothStep(float value, float target, float alpha)
+ ///
+ /// The interpolation result as determined by (1 - alpha) * value + alpha * target.
+ ///
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static TNumber Lerp(TNumber value, TNumber target, TNumber alpha)
+ where TNumber : INumber
{
- alpha = System.Math.Clamp(alpha, 0.0f, 1.0f);
- alpha = -2.0f * alpha * alpha * alpha + 3.0f * alpha * alpha;
- return target * alpha + value * (1.0f - alpha);
+ // rookie mistake: a + t * (b - a)
+ // "precise" method: (1 - t) * a + t * b
+ return ((TNumber.MultiplicativeIdentity - alpha) * value) + (alpha * target);
+ }
+
+ ///
+ /// Returns the incremental sawtooth wave of a given value.
+ ///
+ /// The value to calculate.
+ /// The sawtooth wave of the given value.
+ public static TNumber Sawtooth(TNumber value)
+ where TNumber : IFloatingPoint
+ {
+ return (value - TNumber.Floor(value));
+ }
+
+ ///
+ /// Converts a value from being a percentage of one range, to being the same percentage in a new range.
+ ///
+ /// The value to convert.
+ /// The old minimum value.
+ /// The old maximum value.
+ /// The new minimum value.
+ /// The new maximum value.
+ /// The scaled value.
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static TNumber ScaleRange(TNumber value, TNumber oldMin, TNumber oldMax, TNumber newMin, TNumber newMax)
+ where TNumber : INumber
+ {
+ TNumber oldRange = oldMax - oldMin;
+ TNumber newRange = newMax - newMin;
+ TNumber alpha = (value - oldMin) / oldRange;
+ return (alpha * newRange) + newMin;
}
///
@@ -379,10 +463,16 @@ public static class MathUtility
/// The interpolation target.
/// The interpolation alpha.
/// The interpolation result.
- public static double SmoothStep(double value, double target, double alpha)
+ public static TNumber SmoothStep(TNumber value, TNumber target, TNumber alpha)
+ where TNumber : INumber
{
- alpha = System.Math.Clamp(alpha, 0.0, 1.0);
- alpha = -2.0 * alpha * alpha * alpha + 3.0 * alpha * alpha;
- return target * alpha + value * (1.0 - alpha);
+ TNumber one = TNumber.One;
+ TNumber two = one + one;
+ TNumber three = two + one;
+
+ alpha = TNumber.Clamp(alpha, TNumber.Zero, TNumber.One);
+ alpha = -two * alpha * alpha * alpha + three * alpha * alpha;
+ return target * alpha + value * (one - alpha);
}
+#endif
}
diff --git a/X10D/src/Math/NumberExtensions.cs b/X10D/src/Math/NumberExtensions.cs
new file mode 100644
index 0000000..3a058c5
--- /dev/null
+++ b/X10D/src/Math/NumberExtensions.cs
@@ -0,0 +1,104 @@
+#if NET7_0_OR_GREATER
+using System.Diagnostics.Contracts;
+using System.Numerics;
+using System.Runtime.CompilerServices;
+using X10D.CompilerServices;
+
+namespace X10D.Math;
+
+///
+/// Math-related extension methods for .
+///
+public static class NumberExtensions
+{
+ ///
+ /// Returns a value indicating whether the current value is evenly divisible by 2.
+ ///
+ /// The value whose parity to check.
+ ///
+ /// if is evenly divisible by 2, or
+ /// otherwise.
+ ///
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static bool IsEven(this TNumber value)
+ where TNumber : INumber
+ {
+ return value % TNumber.CreateChecked(2) == TNumber.Zero;
+ }
+
+ ///
+ /// Returns a value indicating whether the current value is not evenly divisible by 2.
+ ///
+ /// The value whose parity to check.
+ ///
+ /// if is not evenly divisible by 2, or
+ /// otherwise.
+ ///
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static bool IsOdd(this TNumber value)
+ where TNumber : INumber
+ {
+ return !value.IsEven();
+ }
+
+ ///
+ /// Performs a modulo operation which supports a negative dividend.
+ ///
+ /// The dividend.
+ /// The divisor.
+ /// The result of dividend mod divisor.
+ ///
+ /// The % 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 x % y where x is
+ /// negative will return a negative value, akin to -(x % y), even if precedence is forced. This method provides a
+ /// modulo operation which supports negative dividends.
+ ///
+ /// ShreevatsaR, https://stackoverflow.com/a/1082938/1467293
+ /// CC-BY-SA 2.5
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static TNumber Mod(this TNumber dividend, TNumber divisor)
+ where TNumber : INumber
+ {
+ TNumber r = dividend % divisor;
+ return r < TNumber.Zero ? r + divisor : r;
+ }
+
+ ///
+ /// Returns an integer that indicates the sign of this number.
+ ///
+ /// A signed number.
+ ///
+ /// A number that indicates the sign of , as shown in the following table.
+ ///
+ ///
+ ///
+ /// Return value
+ /// Meaning
+ ///
+ ///
+ /// -
+ /// -1
+ /// is less than zero.
+ ///
+ /// -
+ /// 0
+ /// is equal to zero.
+ ///
+ /// -
+ /// 1
+ /// is greater than zero.
+ ///
+ ///
+ ///
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static int Sign(this TNumber value)
+ where TNumber : INumber
+ {
+ return TNumber.Sign(value);
+ }
+}
+#endif
diff --git a/X10D/src/Math/SByteExtensions.cs b/X10D/src/Math/SByteExtensions.cs
index a4c18f5..de64ee3 100644
--- a/X10D/src/Math/SByteExtensions.cs
+++ b/X10D/src/Math/SByteExtensions.cs
@@ -10,6 +10,7 @@ namespace X10D.Math;
[CLSCompliant(false)]
public static class SByteExtensions
{
+#if !NET7_0_OR_GREATER
///
/// Returns the number of digits in the current 8-bit signed integer.
///
@@ -113,6 +114,7 @@ public static class SByteExtensions
{
return !value.IsEven();
}
+#endif
///
/// Returns a value indicating whether the current value is a prime number.
@@ -141,6 +143,7 @@ public static class SByteExtensions
return (sbyte)((long)value).LowestCommonMultiple(other);
}
+#if !NET7_0_OR_GREATER
///
/// Performs a modulo operation which supports a negative dividend.
///
@@ -162,6 +165,7 @@ public static class SByteExtensions
int r = dividend % divisor;
return (sbyte)(r < 0 ? r + divisor : r);
}
+#endif
///
/// Returns the multiplicative persistence of a specified value.
diff --git a/X10D/src/Math/UInt16Extensions.cs b/X10D/src/Math/UInt16Extensions.cs
index bffe978..617ed9d 100644
--- a/X10D/src/Math/UInt16Extensions.cs
+++ b/X10D/src/Math/UInt16Extensions.cs
@@ -10,6 +10,7 @@ namespace X10D.Math;
[CLSCompliant(false)]
public static class UInt16Extensions
{
+#if !NET7_0_OR_GREATER
///
/// Returns the number of digits in the current 16-bit signed integer.
///
@@ -94,20 +95,6 @@ public static class UInt16Extensions
return (value & 1) == 0;
}
- ///
- /// Returns a value indicating whether the current value is a prime number.
- ///
- /// The value whose primality to check.
- ///
- /// if is prime; otherwise, .
- ///
- [Pure]
- [MethodImpl(CompilerResources.MaxOptimization)]
- public static bool IsPrime(this ushort value)
- {
- return ((ulong)value).IsPrime();
- }
-
///
/// Returns a value indicating whether the current value is not evenly divisible by 2.
///
@@ -122,6 +109,21 @@ public static class UInt16Extensions
{
return !value.IsEven();
}
+#endif
+
+ ///
+ /// Returns a value indicating whether the current value is a prime number.
+ ///
+ /// The value whose primality to check.
+ ///
+ /// if is prime; otherwise, .
+ ///
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static bool IsPrime(this ushort value)
+ {
+ return ((ulong)value).IsPrime();
+ }
///
/// Calculates the lowest common multiple between the current 16-bit unsigned integer, and another 16-bit unsigned
diff --git a/X10D/src/Math/UInt32Extensions.cs b/X10D/src/Math/UInt32Extensions.cs
index 3177425..da391e9 100644
--- a/X10D/src/Math/UInt32Extensions.cs
+++ b/X10D/src/Math/UInt32Extensions.cs
@@ -10,6 +10,7 @@ namespace X10D.Math;
[CLSCompliant(false)]
public static class UInt32Extensions
{
+#if !NET7_0_OR_GREATER
///
/// Returns the number of digits in the current 32-bit unsigned integer.
///
@@ -94,20 +95,6 @@ public static class UInt32Extensions
return (value & 1) == 0;
}
- ///
- /// Returns a value indicating whether the current value is a prime number.
- ///
- /// The value whose primality to check.
- ///
- /// if is prime; otherwise, .
- ///
- [Pure]
- [MethodImpl(CompilerResources.MaxOptimization)]
- public static bool IsPrime(this uint value)
- {
- return ((ulong)value).IsPrime();
- }
-
///
/// Returns a value indicating whether the current value is not evenly divisible by 2.
///
@@ -122,6 +109,21 @@ public static class UInt32Extensions
{
return !value.IsEven();
}
+#endif
+
+ ///
+ /// Returns a value indicating whether the current value is a prime number.
+ ///
+ /// The value whose primality to check.
+ ///
+ /// if is prime; otherwise, .
+ ///
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static bool IsPrime(this uint value)
+ {
+ return ((ulong)value).IsPrime();
+ }
///
/// Calculates the lowest common multiple between the current 32-bit unsigned integer, and another 32-bit unsigned
diff --git a/X10D/src/Math/UInt64Extensions.cs b/X10D/src/Math/UInt64Extensions.cs
index 029deea..aaec7b4 100644
--- a/X10D/src/Math/UInt64Extensions.cs
+++ b/X10D/src/Math/UInt64Extensions.cs
@@ -10,6 +10,7 @@ namespace X10D.Math;
[CLSCompliant(false)]
public static class UInt64Extensions
{
+#if !NET7_0_OR_GREATER
///
/// Returns the number of digits in the current 64-bit unsigned integer.
///
@@ -99,6 +100,22 @@ public static class UInt64Extensions
return (value & 1) == 0;
}
+ ///
+ /// Returns a value indicating whether the current value is not evenly divisible by 2.
+ ///
+ /// The value whose parity to check.
+ ///
+ /// if is not evenly divisible by 2, or
+ /// otherwise.
+ ///
+ [Pure]
+ [MethodImpl(CompilerResources.MaxOptimization)]
+ public static bool IsOdd(this ulong value)
+ {
+ return !value.IsEven();
+ }
+#endif
+
///
/// Returns a value indicating whether the current value is a prime number.
///
@@ -132,21 +149,6 @@ public static class UInt64Extensions
return true;
}
- ///
- /// Returns a value indicating whether the current value is not evenly divisible by 2.
- ///
- /// The value whose parity to check.
- ///
- /// if is not evenly divisible by 2, or
- /// otherwise.
- ///
- [Pure]
- [MethodImpl(CompilerResources.MaxOptimization)]
- public static bool IsOdd(this ulong value)
- {
- return !value.IsEven();
- }
-
///
/// Calculates the lowest common multiple between the current 64-bit unsigned integer, and another 64-bit unsigned
/// integer.
diff --git a/X10D/src/Time/Int16Extensions.cs b/X10D/src/Time/Int16Extensions.cs
index fc0cfdb..0490c47 100644
--- a/X10D/src/Time/Int16Extensions.cs
+++ b/X10D/src/Time/Int16Extensions.cs
@@ -32,7 +32,7 @@ public static class Int16Extensions
value++;
}
- return value.Mod(4) == 0 && (value.Mod(100) != 0 || value.Mod(400) == 0);
+ return value.Mod((short)4) == 0 && (value.Mod((short)100) != 0 || value.Mod((short)400) == 0);
}
///
diff --git a/X10D/src/Time/SByteExtensions.cs b/X10D/src/Time/SByteExtensions.cs
index babd8d3..fea7719 100644
--- a/X10D/src/Time/SByteExtensions.cs
+++ b/X10D/src/Time/SByteExtensions.cs
@@ -33,7 +33,7 @@ public static class SByteExtensions
value++;
}
- return value.Mod(4) == 0 && value.Mod(100) != 0; // mod 400 not required, sbyte.MaxValue is 127 anyway
+ return value.Mod((sbyte)4) == 0 && value.Mod((sbyte)100) != 0; // mod 400 not required, sbyte.MaxValue is 127 anyway
}
///