public static class BinaryIntegerConstants<T>
where T : IBinaryInteger<T>
public static T Log2Size { get; }
public static T Nine { get; }
public static T Size { get; }
public static T Ten { get; }
static BinaryIntegerConstants()
var size = T.PopCount(value: T.AllBitsSet);
Log2Size = T.Log2(value: size);
Nine = T.CreateChecked(value: 9U);
Ten = T.CreateChecked(value: 10U);
public static class BinaryIntegerFunctions
public static T Exponentiate<T>(this T value, T exponent)
where T : IBinaryInteger<T>
if (T.IsOddInteger(value: exponent))
while (T.Zero < exponent);
public static T LogarithmBase10<T>(this T value)
where T : IBinaryInteger<T>
var bitCount = int.CreateChecked(value: BinaryIntegerConstants<T>.Size);
value = T.Abs(value: value);
#if !FORCE_SOFTWARE_LOG10
8 => (T.CreateTruncating(value: ((uint)MathF.Log10(x: uint.CreateTruncating(value: value)))) + T.One),
16 => (T.CreateTruncating(value: ((uint)MathF.Log10(x: uint.CreateTruncating(value: value)))) + T.One),
32 => (T.CreateTruncating(value: ((uint)Math.Log10(d: uint.CreateTruncating(value: value)))) + T.One),
_ => SoftwareImplementation(value: value),
static T SoftwareImplementation(T value)
quotient /= BinaryIntegerConstants<T>.Ten;
while (T.Zero < quotient);
public static class MyExtensions
public static T RotateDigitsLeft<T>(this T value, int count)
where T : IBinaryInteger<T>
var absoluteValue = T.Abs(value: value);
var countAsT = T.CreateTruncating(value: count);
var digitCount = absoluteValue.LogarithmBase10();
var factor = BinaryIntegerConstants<T>.Ten.Exponentiate(exponent: (digitCount - countAsT));
var endDigits = (absoluteValue / factor);
var startDigits = (absoluteValue - (endDigits * factor));
return T.CopySign(sign: value, value: ((startDigits * BinaryIntegerConstants<T>.Ten.Exponentiate(exponent: countAsT)) + endDigits));
public static void Main()
int resultLeft = value.RotateDigitsLeft(1);
int resultRight = value.RotateDigitsLeft(-1);
Console.WriteLine($"{value} : {resultLeft} : {resultRight}");