diff --git a/X10D.Tests/src/Math/UInt32Tests.cs b/X10D.Tests/src/Math/UInt32Tests.cs
index 445464208..0ea052b7e 100644
--- a/X10D.Tests/src/Math/UInt32Tests.cs
+++ b/X10D.Tests/src/Math/UInt32Tests.cs
@@ -11,8 +11,14 @@ public partial class UInt32Tests
public void DigitalRootShouldBeCorrect()
{
const uint value = 238;
+
+#if NET7_0_OR_GREATER
+ Assert.AreEqual(4, value.DigitalRoot());
+ Assert.AreEqual(4, (-value).DigitalRoot());
+#else
Assert.AreEqual(4U, value.DigitalRoot());
Assert.AreEqual(4U, (-value).DigitalRoot());
+#endif
}
[TestMethod]
diff --git a/X10D.Tests/src/Math/UInt64Tests.cs b/X10D.Tests/src/Math/UInt64Tests.cs
index c5e81baa9..17f60f4a7 100644
--- a/X10D.Tests/src/Math/UInt64Tests.cs
+++ b/X10D.Tests/src/Math/UInt64Tests.cs
@@ -11,12 +11,18 @@ public partial class UInt64Tests
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.
+
+#if NET7_0_OR_GREATER
+ Assert.AreEqual(4, (-(long)value).DigitalRoot());
+ Assert.AreEqual(4, value.DigitalRoot());
+#else
Assert.AreEqual(4U, (-(long)value).DigitalRoot());
+ Assert.AreEqual(4U, value.DigitalRoot());
+#endif
}
[TestMethod]
diff --git a/X10D/src/Math/BigIntegerExtensions.cs b/X10D/src/Math/BigIntegerExtensions.cs
index 4ce5a0d36..ead10ca4c 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
///
/// Computes the digital root of this 8-bit integer.
///
@@ -27,6 +28,7 @@ public static int DigitalRoot(this BigInteger value)
BigInteger root = BigInteger.Abs(value).Mod(9);
return (int)(root == 0 ? 9 : root);
}
+#endif
///
/// Returns the factorial of the current 64-bit signed integer.
@@ -155,6 +157,7 @@ public static BigInteger LowestCommonMultiple(this BigInteger value, BigInteger
return value * other / value.GreatestCommonFactor(other);
}
+#if !NET7_0_OR_GREATER
///
/// Performs a modulo operation which supports a negative dividend.
///
@@ -176,6 +179,7 @@ public static BigInteger Mod(this BigInteger dividend, BigInteger divisor)
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 000000000..94b3728bd
--- /dev/null
+++ b/X10D/src/Math/BinaryIntegerExtensions.cs
@@ -0,0 +1,58 @@
+#if NET7_0_OR_GREATER
+using System.Diagnostics.Contracts;
+using System.Globalization;
+using System.Numerics;
+using System.Runtime.CompilerServices;
+using X10D.CompilerServices;
+
+namespace X10D.Math;
+
+///
+/// Math-related extension methods for .
+///
+public static class BinaryIntegerExtensions
+{
+ ///
+ /// 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.MethodImplOptions)]
+ 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);
+ }
+
+ ///
+ /// 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.MethodImplOptions)]
+ public static TInteger Mod(this TInteger dividend, TInteger divisor)
+ where TInteger : IBinaryInteger
+ {
+ TInteger r = dividend % divisor;
+ return r < TInteger.Zero ? r + divisor : r;
+ }
+}
+#endif
diff --git a/X10D/src/Math/ByteExtensions.cs b/X10D/src/Math/ByteExtensions.cs
index 6a7db3381..0d4ea5670 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
///
/// Computes the digital root of this 8-bit integer.
///
@@ -26,6 +27,7 @@ public static byte DigitalRoot(this byte value)
int root = value % 9;
return (byte)(root == 0 ? 9 : root);
}
+#endif
///
/// Returns the factorial of the current 8-bit unsigned integer.
diff --git a/X10D/src/Math/Int16Extensions.cs b/X10D/src/Math/Int16Extensions.cs
index 7896cf3c7..e4e57ca9e 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
///
/// Computes the digital root of this 16-bit integer.
///
@@ -25,6 +26,7 @@ public static short DigitalRoot(this short value)
short root = System.Math.Abs(value).Mod(9);
return root < 1 ? (short)(9 - root) : root;
}
+#endif
///
/// Returns the factorial of the current 16-bit signed integer.
@@ -125,6 +127,7 @@ public static short LowestCommonMultiple(this short value, short other)
return (short)((long)value).LowestCommonMultiple(other);
}
+#if !NET7_0_OR_GREATER
///
/// Performs a modulo operation which supports a negative dividend.
///
@@ -146,6 +149,7 @@ public static short Mod(this short dividend, short divisor)
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 edaf0dd4e..71df5a317 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
///
/// Computes the digital root of this 32-bit integer.
///
@@ -25,6 +26,7 @@ public static int DigitalRoot(this int value)
int root = System.Math.Abs(value).Mod(9);
return root < 1 ? 9 - root : root;
}
+#endif
///
/// Returns the factorial of the current 32-bit signed integer.
@@ -125,6 +127,7 @@ public static int LowestCommonMultiple(this int value, int other)
return (int)((long)value).LowestCommonMultiple(other);
}
+#if !NET7_0_OR_GREATER
///
/// Performs a modulo operation which supports a negative dividend.
///
@@ -146,6 +149,7 @@ public static int Mod(this int dividend, int divisor)
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 5f888cc77..85405fc41 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
///
/// Computes the digital root of this 64-bit integer.
///
@@ -25,6 +26,7 @@ public static long DigitalRoot(this long value)
long root = System.Math.Abs(value).Mod(9L);
return root < 1L ? 9L - root : root;
}
+#endif
///
/// Returns the factorial of the current 64-bit signed integer.
@@ -164,6 +166,7 @@ public static long LowestCommonMultiple(this long value, long other)
return value * other / value.GreatestCommonFactor(other);
}
+#if !NET7_0_OR_GREATER
///
/// Performs a modulo operation which supports a negative dividend.
///
@@ -185,6 +188,7 @@ public static long Mod(this long dividend, long divisor)
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/SByteExtensions.cs b/X10D/src/Math/SByteExtensions.cs
index cc61037ca..81b827a4e 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
///
/// Computes the digital root of this 32-bit integer.
///
@@ -26,6 +27,7 @@ public static sbyte DigitalRoot(this sbyte value)
int root = System.Math.Abs(value).Mod(9);
return (sbyte)(root < 1 ? 9 - root : root);
}
+#endif
///
/// Returns the factorial of the current 8-bit signed integer.
@@ -126,6 +128,7 @@ public static sbyte LowestCommonMultiple(this sbyte value, sbyte other)
return (sbyte)((long)value).LowestCommonMultiple(other);
}
+#if !NET7_0_OR_GREATER
///
/// Performs a modulo operation which supports a negative dividend.
///
@@ -147,6 +150,7 @@ public static sbyte Mod(this sbyte dividend, sbyte divisor)
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 e118e58f6..95f60e6aa 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
///
/// Computes the digital root of the current 16-bit unsigned integer.
///
@@ -26,6 +27,7 @@ public static ushort DigitalRoot(this ushort value)
var root = (ushort)(value % 9);
return (ushort)(root == 0 ? 9 : root);
}
+#endif
///
/// Returns the factorial of the current 16-bit unsigned integer.
diff --git a/X10D/src/Math/UInt32Extensions.cs b/X10D/src/Math/UInt32Extensions.cs
index 79fed45a3..5661274de 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
///
/// Computes the digital root of the current 32-bit unsigned integer.
///
@@ -26,6 +27,7 @@ public static uint DigitalRoot(this uint value)
uint root = value % 9;
return root == 0 ? 9 : root;
}
+#endif
///
/// Returns the factorial of the current 32-bit unsigned integer.
diff --git a/X10D/src/Math/UInt64Extensions.cs b/X10D/src/Math/UInt64Extensions.cs
index 4bf9365a8..64cb2ce43 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
///
/// Computes the digital root of the current 64-bit unsigned integer.
///
@@ -26,6 +27,7 @@ public static ulong DigitalRoot(this ulong value)
ulong root = value % 9;
return root == 0 ? 9 : root;
}
+#endif
///
/// Returns the factorial of the current 64-bit unsigned integer.
diff --git a/X10D/src/Time/Int16Extensions.cs b/X10D/src/Time/Int16Extensions.cs
index d1644df91..9673aa941 100644
--- a/X10D/src/Time/Int16Extensions.cs
+++ b/X10D/src/Time/Int16Extensions.cs
@@ -32,7 +32,7 @@ public static bool IsLeapYear(this short value)
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 7013e93c7..dccf0a09b 100644
--- a/X10D/src/Time/SByteExtensions.cs
+++ b/X10D/src/Time/SByteExtensions.cs
@@ -33,7 +33,7 @@ public static bool IsLeapYear(this sbyte value)
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
}
///