diff --git a/src/libraries/Common/tests/System/GenericMathHelpers.cs b/src/libraries/Common/tests/System/GenericMathHelpers.cs
index a3729f35b5a8fe..8a3550afaaaaca 100644
--- a/src/libraries/Common/tests/System/GenericMathHelpers.cs
+++ b/src/libraries/Common/tests/System/GenericMathHelpers.cs
@@ -64,6 +64,8 @@ public static TSelf RemainderExpected(TSelf left, TSelf right, DivisionRounding
public static TSelf LeadingZeroCount(TSelf value) => TSelf.LeadingZeroCount(value);
+ public static TSelf Log10(TSelf value) => TSelf.Log10(value);
+
public static TSelf PopCount(TSelf value) => TSelf.PopCount(value);
public static TSelf ReadBigEndian(byte[] source, bool isUnsigned) => TSelf.ReadBigEndian(source, isUnsigned);
diff --git a/src/libraries/System.Private.CoreLib/src/System/Byte.cs b/src/libraries/System.Private.CoreLib/src/System/Byte.cs
index 1c933aaaced78b..331d28cf1d4304 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Byte.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Byte.cs
@@ -281,6 +281,9 @@ object IConvertible.ToType(Type type, IFormatProvider? provider)
///
public static byte LeadingZeroCount(byte value) => (byte)(BitOperations.LeadingZeroCount(value) - 24);
+ ///
+ public static byte Log10(byte value) => (byte)uint.Log10(value);
+
///
public static byte PopCount(byte value) => (byte)BitOperations.PopCount(value);
diff --git a/src/libraries/System.Private.CoreLib/src/System/Char.cs b/src/libraries/System.Private.CoreLib/src/System/Char.cs
index e8ee0692a82d32..42078fa8e05d94 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Char.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Char.cs
@@ -1214,6 +1214,9 @@ public static int ConvertToUtf32(string s, int index)
///
static char IBinaryInteger.LeadingZeroCount(char value) => (char)(BitOperations.LeadingZeroCount(value) - 16);
+ ///
+ static char IBinaryInteger.Log10(char value) => (char)uint.Log10(value);
+
///
static char IBinaryInteger.PopCount(char value) => (char)BitOperations.PopCount(value);
diff --git a/src/libraries/System.Private.CoreLib/src/System/Int128.cs b/src/libraries/System.Private.CoreLib/src/System/Int128.cs
index bfc8e8c8bf0e25..9387db8636ef71 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Int128.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Int128.cs
@@ -726,6 +726,16 @@ private static int LeadingZeroCountAsInt32(Int128 value)
return BitOperations.LeadingZeroCount(value._upper);
}
+ ///
+ public static Int128 Log10(Int128 value)
+ {
+ if (IsNegative(value))
+ {
+ ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
+ }
+ return (Int128)UInt128.Log10((UInt128)value);
+ }
+
///
public static Int128 PopCount(Int128 value)
=> ulong.PopCount(value._lower) + ulong.PopCount(value._upper);
diff --git a/src/libraries/System.Private.CoreLib/src/System/Int16.cs b/src/libraries/System.Private.CoreLib/src/System/Int16.cs
index b1a90999ea5e9e..c6312f3334c01a 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Int16.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Int16.cs
@@ -284,6 +284,16 @@ object IConvertible.ToType(Type type, IFormatProvider? provider)
///
public static short LeadingZeroCount(short value) => (short)(BitOperations.LeadingZeroCount((ushort)value) - 16);
+ ///
+ public static short Log10(short value)
+ {
+ if (value < 0)
+ {
+ ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
+ }
+ return (short)uint.Log10((uint)value);
+ }
+
///
public static short PopCount(short value) => (short)BitOperations.PopCount((ushort)value);
diff --git a/src/libraries/System.Private.CoreLib/src/System/Int32.cs b/src/libraries/System.Private.CoreLib/src/System/Int32.cs
index 7a0cce55bc8099..b48c681f4b0105 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Int32.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Int32.cs
@@ -300,6 +300,17 @@ object IConvertible.ToType(Type type, IFormatProvider? provider)
[Intrinsic]
public static int LeadingZeroCount(int value) => BitOperations.LeadingZeroCount((uint)value);
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static int Log10(int value)
+ {
+ if (value < 0)
+ {
+ ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
+ }
+ return (int)uint.Log10((uint)value);
+ }
+
///
[Intrinsic]
public static int PopCount(int value) => BitOperations.PopCount((uint)value);
diff --git a/src/libraries/System.Private.CoreLib/src/System/Int64.cs b/src/libraries/System.Private.CoreLib/src/System/Int64.cs
index aa07dbb7d0327b..18c343fdac1808 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Int64.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Int64.cs
@@ -297,6 +297,17 @@ object IConvertible.ToType(Type type, IFormatProvider? provider)
[Intrinsic]
public static long LeadingZeroCount(long value) => BitOperations.LeadingZeroCount((ulong)value);
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static long Log10(long value)
+ {
+ if (value < 0)
+ {
+ ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
+ }
+ return (long)ulong.Log10((ulong)value);
+ }
+
///
[Intrinsic]
public static long PopCount(long value) => BitOperations.PopCount((ulong)value);
diff --git a/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs b/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs
index 4abd1b935f0eb5..cd6f768526f722 100644
--- a/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/IntPtr.cs
@@ -320,6 +320,17 @@ public static bool TryParse(ReadOnlySpan s, NumberStyles style, IFormatPro
[Intrinsic]
public static nint LeadingZeroCount(nint value) => BitOperations.LeadingZeroCount((nuint)value);
+ ///
+ public static nint Log10(nint value)
+ {
+ if (value < 0)
+ {
+ ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
+ }
+
+ return (nint)nuint.Log10((nuint)value);
+ }
+
///
[Intrinsic]
public static nint PopCount(nint value) => BitOperations.PopCount((nuint)value);
diff --git a/src/libraries/System.Private.CoreLib/src/System/Numerics/IBinaryInteger.cs b/src/libraries/System.Private.CoreLib/src/System/Numerics/IBinaryInteger.cs
index e44d1bdbd12e84..065519417526ea 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Numerics/IBinaryInteger.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Numerics/IBinaryInteger.cs
@@ -260,6 +260,35 @@ static virtual TSelf Remainder(TSelf left, TSelf right, DivisionRounding mode)
return remainder;
}
+ /// Computes the integer logarithm base 10 of a value.
+ /// The value whose integer logarithm base 10 is to be computed.
+ /// The integer logarithm base 10 of .
+ /// is negative.
+ /// The result of computing the integer logarithm base 10 of zero is zero.
+ static virtual TSelf Log10(TSelf value)
+ {
+ if (!typeof(TSelf).IsValueType)
+ {
+ ArgumentNullException.ThrowIfNull(value);
+ }
+
+ if (TSelf.IsNegative(value))
+ {
+ ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
+ }
+
+ TSelf ten = TSelf.CreateChecked(10);
+ TSelf result = TSelf.Zero;
+
+ while (value >= ten)
+ {
+ value /= ten;
+ result++;
+ }
+
+ return result;
+ }
+
/// Computes the number of leading zero bits in a value.
/// The value whose leading zero bits are to be counted.
/// The number of leading zero bits in .
diff --git a/src/libraries/System.Private.CoreLib/src/System/SByte.cs b/src/libraries/System.Private.CoreLib/src/System/SByte.cs
index 4ba9c4372de61b..c22e77da475053 100644
--- a/src/libraries/System.Private.CoreLib/src/System/SByte.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/SByte.cs
@@ -287,6 +287,16 @@ object IConvertible.ToType(Type type, IFormatProvider? provider)
///
public static sbyte LeadingZeroCount(sbyte value) => (sbyte)(BitOperations.LeadingZeroCount((byte)value) - 24);
+ ///
+ public static sbyte Log10(sbyte value)
+ {
+ if (value < 0)
+ {
+ ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
+ }
+ return (sbyte)uint.Log10((uint)value);
+ }
+
///
public static sbyte PopCount(sbyte value) => (sbyte)BitOperations.PopCount((byte)value);
diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt128.cs b/src/libraries/System.Private.CoreLib/src/System/UInt128.cs
index 20ad904bc423a2..a2be3c33114199 100644
--- a/src/libraries/System.Private.CoreLib/src/System/UInt128.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/UInt128.cs
@@ -797,6 +797,66 @@ private static int LeadingZeroCountAsInt32(UInt128 value)
return BitOperations.LeadingZeroCount(value._upper);
}
+ ///
+ public static UInt128 Log10(UInt128 value)
+ {
+ if (value._upper == 0)
+ {
+ return ulong.Log10(value._lower);
+ }
+
+ // Approximate log10 via log2, then correct with a powers of 10 lookup table.
+ // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+ value |= 1U;
+ uint log2 = (uint)Log2(value) + 1;
+ uint approx = (log2 * 1233) >> 12;
+ return value < PowersOf10[(int)approx] ? approx - 1 : approx;
+ }
+
+ // Lookup table for power-of-10 boundaries corrections
+ private static readonly UInt128[] PowersOf10 =
+ [
+ new UInt128(0, 1UL),
+ new UInt128(0, 10UL),
+ new UInt128(0, 100UL),
+ new UInt128(0, 1_000UL),
+ new UInt128(0, 10_000UL),
+ new UInt128(0, 100_000UL),
+ new UInt128(0, 1_000_000UL),
+ new UInt128(0, 10_000_000UL),
+ new UInt128(0, 100_000_000UL),
+ new UInt128(0, 1_000_000_000UL),
+ new UInt128(0, 10_000_000_000UL),
+ new UInt128(0, 100_000_000_000UL),
+ new UInt128(0, 1_000_000_000_000UL),
+ new UInt128(0, 10_000_000_000_000UL),
+ new UInt128(0, 100_000_000_000_000UL),
+ new UInt128(0, 1_000_000_000_000_000UL),
+ new UInt128(0, 10_000_000_000_000_000UL),
+ new UInt128(0, 100_000_000_000_000_000UL),
+ new UInt128(0, 1_000_000_000_000_000_000UL),
+ new UInt128(0, 10_000_000_000_000_000_000UL),
+ new UInt128(5, 7766279631452241920UL),
+ new UInt128(54, 3875820019684212736UL),
+ new UInt128(542, 1864712049423024128UL),
+ new UInt128(5421, 200376420520689664UL),
+ new UInt128(54210, 2003764205206896640UL),
+ new UInt128(542101, 1590897978359414784UL),
+ new UInt128(5421010, 15908979783594147840UL),
+ new UInt128(54210108, 11515845246265065472UL),
+ new UInt128(542101086, 4477988020393345024UL),
+ new UInt128(5421010862, 7886392056514347008UL),
+ new UInt128(54210108624, 5076944270305263616UL),
+ new UInt128(542101086242, 13875954555633532928UL),
+ new UInt128(5421010862427, 9632337040368467968UL),
+ new UInt128(54210108624275, 4089650035136921600UL),
+ new UInt128(542101086242752, 4003012203950112768UL),
+ new UInt128(5421010862427522, 3136633892082024448UL),
+ new UInt128(54210108624275221, 12919594847110692864UL),
+ new UInt128(542101086242752217, 68739955140067328UL),
+ new UInt128(5421010862427522170, 687399551400673280UL),
+ ];
+
///
public static UInt128 PopCount(UInt128 value)
=> ulong.PopCount(value._lower) + ulong.PopCount(value._upper);
diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt16.cs b/src/libraries/System.Private.CoreLib/src/System/UInt16.cs
index 87d4f12a9a10d9..c477fcaaf56ad5 100644
--- a/src/libraries/System.Private.CoreLib/src/System/UInt16.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/UInt16.cs
@@ -278,6 +278,9 @@ object IConvertible.ToType(Type type, IFormatProvider? provider)
///
public static ushort LeadingZeroCount(ushort value) => (ushort)(BitOperations.LeadingZeroCount(value) - 16);
+ ///
+ public static ushort Log10(ushort value) => (ushort)uint.Log10(value);
+
///
public static ushort PopCount(ushort value) => (ushort)BitOperations.PopCount(value);
diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt32.cs b/src/libraries/System.Private.CoreLib/src/System/UInt32.cs
index a774069fb560b2..dc3282ad146444 100644
--- a/src/libraries/System.Private.CoreLib/src/System/UInt32.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/UInt32.cs
@@ -295,6 +295,35 @@ object IConvertible.ToType(Type type, IFormatProvider? provider)
[Intrinsic]
public static uint LeadingZeroCount(uint value) => (uint)BitOperations.LeadingZeroCount(value);
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static uint Log10(uint value)
+ {
+ // Use Log2 to get approximate Log10 via the relationship:
+ // log10(x) ≈ (log2(x) + 1) * 1233 >> 12
+ // Then correct with a powers-of-10 lookup table.
+ // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+ value |= 1;
+ uint log2 = (uint)BitOperations.Log2(value) + 1;
+ uint approx = (log2 * 1233) >> 12;
+ return value < PowersOf10[(int)approx] ? approx - 1 : approx;
+ }
+
+ // Lookup table for power-of-10 boundaries corrections
+ private static ReadOnlySpan PowersOf10 =>
+ [
+ 1,
+ 10,
+ 100,
+ 1_000,
+ 10_000,
+ 100_000,
+ 1_000_000,
+ 10_000_000,
+ 100_000_000,
+ 1_000_000_000,
+ ];
+
///
[Intrinsic]
public static uint PopCount(uint value) => (uint)BitOperations.PopCount(value);
diff --git a/src/libraries/System.Private.CoreLib/src/System/UInt64.cs b/src/libraries/System.Private.CoreLib/src/System/UInt64.cs
index 56d9fc2cc2015a..8abc0f1b5a4a9d 100644
--- a/src/libraries/System.Private.CoreLib/src/System/UInt64.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/UInt64.cs
@@ -294,6 +294,43 @@ object IConvertible.ToType(Type type, IFormatProvider? provider)
[Intrinsic]
public static ulong LeadingZeroCount(ulong value) => (ulong)BitOperations.LeadingZeroCount(value);
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ulong Log10(ulong value)
+ {
+ // Approximate log10 via log2, then correct with a powers of 10 lookup table.
+ // http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10
+ value |= 1;
+ uint log2 = (uint)BitOperations.Log2(value) + 1;
+ uint approx = (log2 * 1233) >> 12;
+ return value < PowersOf10[(int)approx] ? approx - 1 : approx;
+ }
+
+ // Lookup table for power-of-10 boundaries corrections
+ private static ReadOnlySpan PowersOf10 =>
+ [
+ 1,
+ 10,
+ 100,
+ 1_000,
+ 10_000,
+ 100_000,
+ 1_000_000,
+ 10_000_000,
+ 100_000_000,
+ 1_000_000_000,
+ 10_000_000_000,
+ 100_000_000_000,
+ 1_000_000_000_000,
+ 10_000_000_000_000,
+ 100_000_000_000_000,
+ 1_000_000_000_000_000,
+ 10_000_000_000_000_000,
+ 100_000_000_000_000_000,
+ 1_000_000_000_000_000_000,
+ 10_000_000_000_000_000_000,
+ ];
+
///
[Intrinsic]
public static ulong PopCount(ulong value) => (ulong)BitOperations.PopCount(value);
diff --git a/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs b/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs
index 450160040fb4f7..fe1f01e314ab58 100644
--- a/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/UIntPtr.cs
@@ -316,6 +316,16 @@ public static bool TryParse(ReadOnlySpan s, NumberStyles style, IFormatPro
[Intrinsic]
public static nuint LeadingZeroCount(nuint value) => (nuint)BitOperations.LeadingZeroCount(value);
+ ///
+ public static nuint Log10(nuint value)
+ {
+#if TARGET_64BIT
+ return (nuint)ulong.Log10((ulong)value);
+#else
+ return (nuint)uint.Log10((uint)value);
+#endif
+ }
+
///
[Intrinsic]
public static nuint PopCount(nuint value) => (nuint)BitOperations.PopCount(value);
diff --git a/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs b/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs
index 9c3e42270020ca..e080d40f99ce11 100644
--- a/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs
+++ b/src/libraries/System.Runtime.Numerics/ref/System.Runtime.Numerics.cs
@@ -200,6 +200,7 @@ namespace System.Numerics
public static System.Numerics.BigInteger Subtract(System.Numerics.BigInteger left, System.Numerics.BigInteger right) { throw null; }
int System.Numerics.IBinaryInteger.GetByteCount() { throw null; }
int System.Numerics.IBinaryInteger.GetShortestBitLength() { throw null; }
+ static System.Numerics.BigInteger System.Numerics.IBinaryInteger.Log10(System.Numerics.BigInteger value) { throw null; }
static bool System.Numerics.IBinaryInteger.TryReadBigEndian(System.ReadOnlySpan source, bool isUnsigned, out System.Numerics.BigInteger value) { throw null; }
static bool System.Numerics.IBinaryInteger.TryReadLittleEndian(System.ReadOnlySpan source, bool isUnsigned, out System.Numerics.BigInteger value) { throw null; }
bool System.Numerics.IBinaryInteger.TryWriteBigEndian(System.Span destination, out int bytesWritten) { throw null; }
diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
index aa6389fcf94c8f..10ea7468af201e 100644
--- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
+++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
@@ -3141,6 +3141,36 @@ private void AssertValid()
// IBinaryInteger
//
+ ///
+ static BigInteger IBinaryInteger.Log10(BigInteger value)
+ {
+ value.AssertValid();
+
+ if (IsNegative(value))
+ {
+ ThrowHelper.ThrowValueArgumentOutOfRange_NeedNonNegNumException();
+ }
+
+ // For small values stored in _sign, use the fast path
+ if (value._bits is null)
+ {
+ return uint.Log10((uint)value._sign);
+ }
+
+ // For large values, use Log2-based estimation with single correction.
+ // log10(x) = log2(x) * log10(2); we approximate log10(2) as N/2^S.
+ // The smaller fixed-width types (uint, ulong, UInt128) use 1233/4096
+ // (~4.6e-6 error per bit), which is sufficient for up to ~217K bits.
+ // For BigInteger, which has no upper bound on bit count, we use
+ // 1292913986/2^32 (~1.1e-10 error per bit), safe up to ~8.7B bits,
+ // which covers the full BigInteger range.
+ BigInteger log2Value = Log2(value);
+ BigInteger approx = ((log2Value + 1) * 1292913986L) >> 32;
+ BigInteger power = Pow(10, (int)approx);
+
+ return value < power ? approx - 1 : approx;
+ }
+
///
public static (BigInteger Quotient, BigInteger Remainder) DivRem(BigInteger left, BigInteger right)
{
diff --git a/src/libraries/System.Runtime.Numerics/tests/BigIntegerTests.GenericMath.cs b/src/libraries/System.Runtime.Numerics/tests/BigIntegerTests.GenericMath.cs
index 721ac8bc3fe9d7..e5fb00728bffc7 100644
--- a/src/libraries/System.Runtime.Numerics/tests/BigIntegerTests.GenericMath.cs
+++ b/src/libraries/System.Runtime.Numerics/tests/BigIntegerTests.GenericMath.cs
@@ -206,6 +206,46 @@ public static void DivRemTest()
Assert.Equal((Int64MaxValue, One), BinaryIntegerHelper.DivRem(UInt64MaxValue, 2));
}
+ [Fact]
+ public static void Log10Test()
+ {
+ Assert.Equal((BigInteger)0, BinaryIntegerHelper.Log10(Zero));
+ Assert.Equal((BigInteger)0, BinaryIntegerHelper.Log10(One));
+
+ BigInteger power = 1;
+ for (int n = 0; n < 25; n++)
+ {
+ Assert.Equal((BigInteger)n, BinaryIntegerHelper.Log10(power));
+ if (power > 1)
+ {
+ Assert.Equal((BigInteger)(n - 1), BinaryIntegerHelper.Log10(power - 1));
+ }
+ power *= 10;
+ }
+
+ Assert.Equal((BigInteger)18, BinaryIntegerHelper.Log10(Int64MaxValue));
+ Assert.Throws(() => BinaryIntegerHelper.Log10(NegativeOne));
+ Assert.Throws(() => BinaryIntegerHelper.Log10(Int64MinValue));
+ }
+
+ [Fact]
+ public static void Log10Test_LargeValues()
+ {
+ // 2^681 produces log10 = 205, verifying correctness for values
+ // beyond the fixed-width type range.
+ Assert.Equal((BigInteger)205, BinaryIntegerHelper.Log10(BigInteger.Pow(2, 681)));
+ }
+
+ [Fact]
+ [OuterLoop]
+ public static void Log10Test_VeryLargeValues()
+ {
+ // 2^217769 produces log10 = 65555, verifying correctness for
+ // very large values where a less precise approximation constant
+ // would fail.
+ Assert.Equal((BigInteger)65555, BinaryIntegerHelper.Log10(BigInteger.Pow(2, 217769)));
+ }
+
[Fact]
public static void LeadingZeroCountTest()
{
diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs
index 6bb8a8766c5e88..fe3fa7b429897b 100644
--- a/src/libraries/System.Runtime/ref/System.Runtime.cs
+++ b/src/libraries/System.Runtime/ref/System.Runtime.cs
@@ -965,6 +965,7 @@ public static void SetByte(System.Array array, int index, byte value) { }
public static bool IsOddInteger(byte value) { throw null; }
public static bool IsPow2(byte value) { throw null; }
public static byte LeadingZeroCount(byte value) { throw null; }
+ public static byte Log10(byte value) { throw null; }
public static byte Log2(byte value) { throw null; }
public static byte Max(byte x, byte y) { throw null; }
public static byte Min(byte x, byte y) { throw null; }
@@ -1182,6 +1183,7 @@ public CannotUnloadAppDomainException(string? message, System.Exception? innerEx
int System.Numerics.IBinaryInteger.GetByteCount() { throw null; }
int System.Numerics.IBinaryInteger.GetShortestBitLength() { throw null; }
static char System.Numerics.IBinaryInteger.LeadingZeroCount(char value) { throw null; }
+ static char System.Numerics.IBinaryInteger.Log10(char value) { throw null; }
static char System.Numerics.IBinaryInteger.PopCount(char value) { throw null; }
static char System.Numerics.IBinaryInteger.RotateLeft(char value, int rotateAmount) { throw null; }
static char System.Numerics.IBinaryInteger.RotateRight(char value, int rotateAmount) { throw null; }
@@ -3612,6 +3614,7 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep
public static bool IsPositive(System.Int128 value) { throw null; }
public static bool IsPow2(System.Int128 value) { throw null; }
public static System.Int128 LeadingZeroCount(System.Int128 value) { throw null; }
+ public static System.Int128 Log10(System.Int128 value) { throw null; }
public static System.Int128 Log2(System.Int128 value) { throw null; }
public static System.Int128 Max(System.Int128 x, System.Int128 y) { throw null; }
public static System.Int128 MaxMagnitude(System.Int128 x, System.Int128 y) { throw null; }
@@ -3799,6 +3802,7 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep
public static bool IsPositive(short value) { throw null; }
public static bool IsPow2(short value) { throw null; }
public static short LeadingZeroCount(short value) { throw null; }
+ public static short Log10(short value) { throw null; }
public static short Log2(short value) { throw null; }
public static short Max(short x, short y) { throw null; }
public static short MaxMagnitude(short x, short y) { throw null; }
@@ -3940,6 +3944,7 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep
public static bool IsPositive(int value) { throw null; }
public static bool IsPow2(int value) { throw null; }
public static int LeadingZeroCount(int value) { throw null; }
+ public static int Log10(int value) { throw null; }
public static int Log2(int value) { throw null; }
public static int Max(int x, int y) { throw null; }
public static int MaxMagnitude(int x, int y) { throw null; }
@@ -4081,6 +4086,7 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep
public static bool IsPositive(long value) { throw null; }
public static bool IsPow2(long value) { throw null; }
public static long LeadingZeroCount(long value) { throw null; }
+ public static long Log10(long value) { throw null; }
public static long Log2(long value) { throw null; }
public static long Max(long x, long y) { throw null; }
public static long MaxMagnitude(long x, long y) { throw null; }
@@ -4228,6 +4234,7 @@ public InsufficientMemoryException(string? message, System.Exception? innerExcep
public static bool IsPositive(nint value) { throw null; }
public static bool IsPow2(nint value) { throw null; }
public static nint LeadingZeroCount(nint value) { throw null; }
+ public static nint Log10(nint value) { throw null; }
public static nint Log2(nint value) { throw null; }
public static nint Max(nint x, nint y) { throw null; }
public static nint MaxMagnitude(nint x, nint y) { throw null; }
@@ -5242,6 +5249,7 @@ public void GetObjectData(System.Runtime.Serialization.SerializationInfo info, S
public static bool IsPositive(sbyte value) { throw null; }
public static bool IsPow2(sbyte value) { throw null; }
public static sbyte LeadingZeroCount(sbyte value) { throw null; }
+ public static sbyte Log10(sbyte value) { throw null; }
public static sbyte Log2(sbyte value) { throw null; }
public static sbyte Max(sbyte x, sbyte y) { throw null; }
public static sbyte MaxMagnitude(sbyte x, sbyte y) { throw null; }
@@ -6901,6 +6909,7 @@ public TypeUnloadedException(string? message, System.Exception? innerException)
public static bool IsOddInteger(System.UInt128 value) { throw null; }
public static bool IsPow2(System.UInt128 value) { throw null; }
public static System.UInt128 LeadingZeroCount(System.UInt128 value) { throw null; }
+ public static System.UInt128 Log10(System.UInt128 value) { throw null; }
public static System.UInt128 Log2(System.UInt128 value) { throw null; }
public static System.UInt128 Max(System.UInt128 x, System.UInt128 y) { throw null; }
public static System.UInt128 Min(System.UInt128 x, System.UInt128 y) { throw null; }
@@ -7094,6 +7103,7 @@ public TypeUnloadedException(string? message, System.Exception? innerException)
public static bool IsOddInteger(ushort value) { throw null; }
public static bool IsPow2(ushort value) { throw null; }
public static ushort LeadingZeroCount(ushort value) { throw null; }
+ public static ushort Log10(ushort value) { throw null; }
public static ushort Log2(ushort value) { throw null; }
public static ushort Max(ushort x, ushort y) { throw null; }
public static ushort Min(ushort x, ushort y) { throw null; }
@@ -7235,6 +7245,7 @@ public TypeUnloadedException(string? message, System.Exception? innerException)
public static bool IsOddInteger(uint value) { throw null; }
public static bool IsPow2(uint value) { throw null; }
public static uint LeadingZeroCount(uint value) { throw null; }
+ public static uint Log10(uint value) { throw null; }
public static uint Log2(uint value) { throw null; }
public static uint Max(uint x, uint y) { throw null; }
public static uint Min(uint x, uint y) { throw null; }
@@ -7376,6 +7387,7 @@ public TypeUnloadedException(string? message, System.Exception? innerException)
public static bool IsOddInteger(ulong value) { throw null; }
public static bool IsPow2(ulong value) { throw null; }
public static ulong LeadingZeroCount(ulong value) { throw null; }
+ public static ulong Log10(ulong value) { throw null; }
public static ulong Log2(ulong value) { throw null; }
public static ulong Max(ulong x, ulong y) { throw null; }
public static ulong Min(ulong x, ulong y) { throw null; }
@@ -7522,6 +7534,7 @@ public TypeUnloadedException(string? message, System.Exception? innerException)
public static bool IsOddInteger(nuint value) { throw null; }
public static bool IsPow2(nuint value) { throw null; }
public static nuint LeadingZeroCount(nuint value) { throw null; }
+ public static nuint Log10(nuint value) { throw null; }
public static nuint Log2(nuint value) { throw null; }
public static nuint Max(nuint x, nuint y) { throw null; }
public static nuint Min(nuint x, nuint y) { throw null; }
@@ -11621,6 +11634,7 @@ public partial interface IBinaryInteger : System.IComparable, System.ICom
static virtual TSelf Remainder(TSelf left, TSelf right, System.Numerics.DivisionRounding mode) { throw null; }
int GetByteCount();
int GetShortestBitLength();
+ static virtual TSelf Log10(TSelf value) { throw null; }
static virtual TSelf LeadingZeroCount(TSelf value) { throw null; }
static abstract TSelf PopCount(TSelf value);
static virtual TSelf ReadBigEndian(byte[] source, bool isUnsigned) { throw null; }
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ByteTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ByteTests.GenericMath.cs
index f61cac08977f1f..c98230725abf21 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ByteTests.GenericMath.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/ByteTests.GenericMath.cs
@@ -180,6 +180,20 @@ public static void LeadingZeroCountTest()
Assert.Equal((byte)0x00, BinaryIntegerHelper.LeadingZeroCount((byte)0xFF));
}
+ [Fact]
+ public static void Log10Test()
+ {
+ Assert.Equal((byte)0, BinaryIntegerHelper.Log10((byte)0));
+ Assert.Equal((byte)0, BinaryIntegerHelper.Log10((byte)1));
+ Assert.Equal((byte)0, BinaryIntegerHelper.Log10((byte)9));
+ Assert.Equal((byte)1, BinaryIntegerHelper.Log10((byte)10));
+ Assert.Equal((byte)1, BinaryIntegerHelper.Log10((byte)99));
+ Assert.Equal((byte)2, BinaryIntegerHelper.Log10((byte)100));
+ Assert.Equal((byte)2, BinaryIntegerHelper.Log10((byte)127));
+ Assert.Equal((byte)2, BinaryIntegerHelper.Log10((byte)128));
+ Assert.Equal((byte)2, BinaryIntegerHelper.Log10((byte)255));
+ }
+
[Fact]
public static void PopCountTest()
{
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/CharTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/CharTests.GenericMath.cs
index fbdc9862c29dc7..c6e19a47df6872 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/CharTests.GenericMath.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/CharTests.GenericMath.cs
@@ -179,6 +179,24 @@ public static void LeadingZeroCountTest()
Assert.Equal((char)0x0000, BinaryIntegerHelper.LeadingZeroCount((char)0xFFFF));
}
+ [Fact]
+ public static void Log10Test()
+ {
+ Assert.Equal((char)0, BinaryIntegerHelper.Log10((char)0));
+ Assert.Equal((char)0, BinaryIntegerHelper.Log10((char)1));
+ Assert.Equal((char)0, BinaryIntegerHelper.Log10((char)9));
+ Assert.Equal((char)1, BinaryIntegerHelper.Log10((char)10));
+ Assert.Equal((char)1, BinaryIntegerHelper.Log10((char)99));
+ Assert.Equal((char)2, BinaryIntegerHelper.Log10((char)100));
+ Assert.Equal((char)2, BinaryIntegerHelper.Log10((char)999));
+ Assert.Equal((char)3, BinaryIntegerHelper.Log10((char)1000));
+ Assert.Equal((char)3, BinaryIntegerHelper.Log10((char)9999));
+ Assert.Equal((char)4, BinaryIntegerHelper.Log10((char)10000));
+ Assert.Equal((char)4, BinaryIntegerHelper.Log10((char)32767));
+ Assert.Equal((char)4, BinaryIntegerHelper.Log10((char)32768));
+ Assert.Equal((char)4, BinaryIntegerHelper.Log10((char)65535));
+ }
+
[Fact]
public static void PopCountTest()
{
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int128Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int128Tests.GenericMath.cs
index 6b3a9bc643b37f..e2986a79883746 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int128Tests.GenericMath.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int128Tests.GenericMath.cs
@@ -229,6 +229,28 @@ public static void LeadingZeroCountTest()
Assert.Equal(0x00, BinaryIntegerHelper.LeadingZeroCount(NegativeOne));
}
+ [Fact]
+ public static void Log10Test()
+ {
+ Assert.Equal(0, BinaryIntegerHelper.Log10(Zero));
+ Assert.Equal(0, BinaryIntegerHelper.Log10(One));
+
+ Int128 power = 1;
+ for (int n = 0; n < 38; n++)
+ {
+ Assert.Equal((Int128)n, BinaryIntegerHelper.Log10(power));
+ if (power > 1)
+ {
+ Assert.Equal((Int128)(n - 1), BinaryIntegerHelper.Log10(power - 1));
+ }
+ power *= 10;
+ }
+
+ Assert.Equal(38, BinaryIntegerHelper.Log10(MaxValue));
+ Assert.Throws(() => BinaryIntegerHelper.Log10(MinValue));
+ Assert.Throws(() => BinaryIntegerHelper.Log10(NegativeOne));
+ }
+
[Fact]
public static void PopCountTest()
{
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int16Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int16Tests.GenericMath.cs
index c2c2baeadb585b..44f3f57461faec 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int16Tests.GenericMath.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int16Tests.GenericMath.cs
@@ -192,6 +192,24 @@ public static void LeadingZeroCountTest()
Assert.Equal((short)0x0000, BinaryIntegerHelper.LeadingZeroCount(unchecked((short)0xFFFF)));
}
+ [Fact]
+ public static void Log10Test()
+ {
+ Assert.Equal((short)0, BinaryIntegerHelper.Log10((short)0));
+ Assert.Equal((short)0, BinaryIntegerHelper.Log10((short)1));
+ Assert.Equal((short)0, BinaryIntegerHelper.Log10((short)9));
+ Assert.Equal((short)1, BinaryIntegerHelper.Log10((short)10));
+ Assert.Equal((short)1, BinaryIntegerHelper.Log10((short)99));
+ Assert.Equal((short)2, BinaryIntegerHelper.Log10((short)100));
+ Assert.Equal((short)2, BinaryIntegerHelper.Log10((short)999));
+ Assert.Equal((short)3, BinaryIntegerHelper.Log10((short)1000));
+ Assert.Equal((short)3, BinaryIntegerHelper.Log10((short)9999));
+ Assert.Equal((short)4, BinaryIntegerHelper.Log10((short)10000));
+ Assert.Equal((short)4, BinaryIntegerHelper.Log10((short)32767));
+ Assert.Throws(() => BinaryIntegerHelper.Log10((short)(-32768)));
+ Assert.Throws(() => BinaryIntegerHelper.Log10((short)(-1)));
+ }
+
[Fact]
public static void PopCountTest()
{
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int32Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int32Tests.GenericMath.cs
index 5d98e93a7084a8..a6166828336e85 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int32Tests.GenericMath.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int32Tests.GenericMath.cs
@@ -192,6 +192,34 @@ public static void LeadingZeroCountTest()
Assert.Equal((int)0x00000000, BinaryIntegerHelper.LeadingZeroCount(unchecked((int)0xFFFFFFFF)));
}
+ [Fact]
+ public static void Log10Test()
+ {
+ Assert.Equal(0, BinaryIntegerHelper.Log10(0));
+ Assert.Equal(0, BinaryIntegerHelper.Log10(1));
+ Assert.Equal(0, BinaryIntegerHelper.Log10(9));
+ Assert.Equal(1, BinaryIntegerHelper.Log10(10));
+ Assert.Equal(1, BinaryIntegerHelper.Log10(99));
+ Assert.Equal(2, BinaryIntegerHelper.Log10(100));
+ Assert.Equal(2, BinaryIntegerHelper.Log10(999));
+ Assert.Equal(3, BinaryIntegerHelper.Log10(1_000));
+ Assert.Equal(3, BinaryIntegerHelper.Log10(9_999));
+ Assert.Equal(4, BinaryIntegerHelper.Log10(10_000));
+ Assert.Equal(4, BinaryIntegerHelper.Log10(99_999));
+ Assert.Equal(5, BinaryIntegerHelper.Log10(100_000));
+ Assert.Equal(5, BinaryIntegerHelper.Log10(999_999));
+ Assert.Equal(6, BinaryIntegerHelper.Log10(1_000_000));
+ Assert.Equal(6, BinaryIntegerHelper.Log10(9_999_999));
+ Assert.Equal(7, BinaryIntegerHelper.Log10(10_000_000));
+ Assert.Equal(7, BinaryIntegerHelper.Log10(99_999_999));
+ Assert.Equal(8, BinaryIntegerHelper.Log10(100_000_000));
+ Assert.Equal(8, BinaryIntegerHelper.Log10(999_999_999));
+ Assert.Equal(9, BinaryIntegerHelper.Log10(1_000_000_000));
+ Assert.Equal(9, BinaryIntegerHelper.Log10(2_147_483_647));
+ Assert.Throws(() => BinaryIntegerHelper.Log10(-2_147_483_648));
+ Assert.Throws(() => BinaryIntegerHelper.Log10(-1));
+ }
+
[Fact]
public static void PopCountTest()
{
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int64Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int64Tests.GenericMath.cs
index 46561b30232607..2f2fc0098fac91 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int64Tests.GenericMath.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Int64Tests.GenericMath.cs
@@ -192,6 +192,52 @@ public static void LeadingZeroCountTest()
Assert.Equal((long)0x0000000000000000, BinaryIntegerHelper.LeadingZeroCount(unchecked((long)0xFFFFFFFFFFFFFFFF)));
}
+ [Fact]
+ public static void Log10Test()
+ {
+ Assert.Equal((long)0, BinaryIntegerHelper.Log10((long)0));
+ Assert.Equal((long)0, BinaryIntegerHelper.Log10((long)1));
+ Assert.Equal((long)0, BinaryIntegerHelper.Log10((long)9));
+ Assert.Equal((long)1, BinaryIntegerHelper.Log10((long)10));
+ Assert.Equal((long)1, BinaryIntegerHelper.Log10((long)99));
+ Assert.Equal((long)2, BinaryIntegerHelper.Log10((long)100));
+ Assert.Equal((long)2, BinaryIntegerHelper.Log10((long)999));
+ Assert.Equal((long)3, BinaryIntegerHelper.Log10((long)1_000));
+ Assert.Equal((long)3, BinaryIntegerHelper.Log10((long)9_999));
+ Assert.Equal((long)4, BinaryIntegerHelper.Log10((long)10_000));
+ Assert.Equal((long)4, BinaryIntegerHelper.Log10((long)99_999));
+ Assert.Equal((long)5, BinaryIntegerHelper.Log10((long)100_000));
+ Assert.Equal((long)5, BinaryIntegerHelper.Log10((long)999_999));
+ Assert.Equal((long)6, BinaryIntegerHelper.Log10((long)1_000_000));
+ Assert.Equal((long)6, BinaryIntegerHelper.Log10((long)9_999_999));
+ Assert.Equal((long)7, BinaryIntegerHelper.Log10((long)10_000_000));
+ Assert.Equal((long)7, BinaryIntegerHelper.Log10((long)99_999_999));
+ Assert.Equal((long)8, BinaryIntegerHelper.Log10((long)100_000_000));
+ Assert.Equal((long)8, BinaryIntegerHelper.Log10((long)999_999_999));
+ Assert.Equal((long)9, BinaryIntegerHelper.Log10((long)1_000_000_000));
+ Assert.Equal((long)9, BinaryIntegerHelper.Log10((long)9_999_999_999));
+ Assert.Equal((long)10, BinaryIntegerHelper.Log10((long)10_000_000_000));
+ Assert.Equal((long)10, BinaryIntegerHelper.Log10((long)99_999_999_999));
+ Assert.Equal((long)11, BinaryIntegerHelper.Log10((long)100_000_000_000));
+ Assert.Equal((long)11, BinaryIntegerHelper.Log10((long)999_999_999_999));
+ Assert.Equal((long)12, BinaryIntegerHelper.Log10((long)1_000_000_000_000));
+ Assert.Equal((long)12, BinaryIntegerHelper.Log10((long)9_999_999_999_999));
+ Assert.Equal((long)13, BinaryIntegerHelper.Log10((long)10_000_000_000_000));
+ Assert.Equal((long)13, BinaryIntegerHelper.Log10((long)99_999_999_999_999));
+ Assert.Equal((long)14, BinaryIntegerHelper.Log10((long)100_000_000_000_000));
+ Assert.Equal((long)14, BinaryIntegerHelper.Log10((long)999_999_999_999_999));
+ Assert.Equal((long)15, BinaryIntegerHelper.Log10((long)1_000_000_000_000_000));
+ Assert.Equal((long)15, BinaryIntegerHelper.Log10((long)9_999_999_999_999_999));
+ Assert.Equal((long)16, BinaryIntegerHelper.Log10((long)10_000_000_000_000_000));
+ Assert.Equal((long)16, BinaryIntegerHelper.Log10((long)99_999_999_999_999_999));
+ Assert.Equal((long)17, BinaryIntegerHelper.Log10((long)100_000_000_000_000_000));
+ Assert.Equal((long)17, BinaryIntegerHelper.Log10((long)999_999_999_999_999_999));
+ Assert.Equal((long)18, BinaryIntegerHelper.Log10((long)1_000_000_000_000_000_000));
+ Assert.Equal((long)18, BinaryIntegerHelper.Log10((long)9_223_372_036_854_775_807));
+ Assert.Throws(() => BinaryIntegerHelper.Log10(-9_223_372_036_854_775_808));
+ Assert.Throws(() => BinaryIntegerHelper.Log10(-1));
+ }
+
[Fact]
public static void PopCountTest()
{
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IntPtrTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IntPtrTests.GenericMath.cs
index 18ab5ad3f276ae..cfac7e4164c2aa 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IntPtrTests.GenericMath.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/IntPtrTests.GenericMath.cs
@@ -343,6 +343,33 @@ public static void LeadingZeroCountTest()
}
}
+ [Fact]
+ public static void Log10Test()
+ {
+ if (Environment.Is64BitProcess)
+ {
+ Assert.Equal(unchecked((nint)0), BinaryIntegerHelper.Log10(unchecked((nint)0)));
+ Assert.Equal(unchecked((nint)0), BinaryIntegerHelper.Log10(unchecked((nint)1)));
+ Assert.Equal(unchecked((nint)0), BinaryIntegerHelper.Log10(unchecked((nint)9)));
+ Assert.Equal(unchecked((nint)1), BinaryIntegerHelper.Log10(unchecked((nint)10)));
+ Assert.Equal(unchecked((nint)2), BinaryIntegerHelper.Log10(unchecked((nint)100)));
+ Assert.Equal(unchecked((nint)18), BinaryIntegerHelper.Log10(unchecked((nint)9_223_372_036_854_775_807)));
+ Assert.Throws(() => BinaryIntegerHelper.Log10(unchecked((nint)0x8000000000000000)));
+ Assert.Throws(() => BinaryIntegerHelper.Log10(unchecked((nint)0xFFFFFFFFFFFFFFFF)));
+ }
+ else
+ {
+ Assert.Equal((nint)0, BinaryIntegerHelper.Log10((nint)0));
+ Assert.Equal((nint)0, BinaryIntegerHelper.Log10((nint)1));
+ Assert.Equal((nint)0, BinaryIntegerHelper.Log10((nint)9));
+ Assert.Equal((nint)1, BinaryIntegerHelper.Log10((nint)10));
+ Assert.Equal((nint)2, BinaryIntegerHelper.Log10((nint)100));
+ Assert.Equal((nint)9, BinaryIntegerHelper.Log10((nint)2_147_483_647));
+ Assert.Throws(() => BinaryIntegerHelper.Log10(unchecked((nint)0x80000000)));
+ Assert.Throws(() => BinaryIntegerHelper.Log10(unchecked((nint)0xFFFFFFFF)));
+ }
+ }
+
[Fact]
public static void PopCountTest()
{
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Numerics/DimTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Numerics/DimTests.GenericMath.cs
index 45c86664f6e597..cdcf4898609f45 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Numerics/DimTests.GenericMath.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/Numerics/DimTests.GenericMath.cs
@@ -316,6 +316,30 @@ public static void LeadingZeroCountUInt32Test()
Assert.Equal((BinaryIntegerWrapper)0x00000000, BinaryIntegerHelper>.LeadingZeroCount((uint)0xFFFFFFFF));
}
+ [Fact]
+ public static void Log10Int32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0, BinaryIntegerHelper>.Log10((int)0));
+ Assert.Equal((BinaryIntegerWrapper)0, BinaryIntegerHelper>.Log10((int)1));
+ Assert.Equal((BinaryIntegerWrapper)0, BinaryIntegerHelper>.Log10((int)9));
+ Assert.Equal((BinaryIntegerWrapper)1, BinaryIntegerHelper>.Log10((int)10));
+ Assert.Equal((BinaryIntegerWrapper)2, BinaryIntegerHelper>.Log10((int)100));
+ Assert.Equal((BinaryIntegerWrapper)9, BinaryIntegerHelper>.Log10(int.MaxValue));
+ Assert.Throws(() => BinaryIntegerHelper>.Log10(int.MinValue));
+ Assert.Throws(() => BinaryIntegerHelper>.Log10((int)(-1)));
+ }
+
+ [Fact]
+ public static void Log10UInt32Test()
+ {
+ Assert.Equal((BinaryIntegerWrapper)0, BinaryIntegerHelper>.Log10((uint)0));
+ Assert.Equal((BinaryIntegerWrapper)0, BinaryIntegerHelper>.Log10((uint)1));
+ Assert.Equal((BinaryIntegerWrapper)0, BinaryIntegerHelper>.Log10((uint)9));
+ Assert.Equal((BinaryIntegerWrapper)1, BinaryIntegerHelper>.Log10((uint)10));
+ Assert.Equal((BinaryIntegerWrapper)2, BinaryIntegerHelper>.Log10((uint)100));
+ Assert.Equal((BinaryIntegerWrapper)9, BinaryIntegerHelper>.Log10(uint.MaxValue));
+ }
+
[Fact]
public static void RotateLeftInt32Test()
{
@@ -716,6 +740,12 @@ public int CompareTo(object? obj)
static bool INumberBase>.TryConvertFromChecked(TOther value, out BinaryIntegerWrapper result)
{
+ if (typeof(TOther) == typeof(T))
+ {
+ result = (T)(object)value;
+ return true;
+ }
+
bool succeeded = T.TryConvertFromChecked(value, out T actualResult);
if (!succeeded)
@@ -728,6 +758,12 @@ static bool INumberBase>.TryConvertFromChecked(T
}
static bool INumberBase>.TryConvertFromSaturating(TOther value, out BinaryIntegerWrapper result)
{
+ if (typeof(TOther) == typeof(T))
+ {
+ result = (T)(object)value;
+ return true;
+ }
+
bool succeeded = T.TryConvertFromSaturating(value, out T actualResult);
if (!succeeded)
@@ -740,6 +776,12 @@ static bool INumberBase>.TryConvertFromSaturating>.TryConvertFromTruncating(TOther value, out BinaryIntegerWrapper result)
{
+ if (typeof(TOther) == typeof(T))
+ {
+ result = (T)(object)value;
+ return true;
+ }
+
bool succeeded = T.TryConvertFromTruncating(value, out T actualResult);
if (!succeeded)
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SByteTests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SByteTests.GenericMath.cs
index 82a0f58cbf5b3d..48412bf11c52ee 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SByteTests.GenericMath.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/SByteTests.GenericMath.cs
@@ -192,6 +192,20 @@ public static void LeadingZeroCountTest()
Assert.Equal((sbyte)0x00, BinaryIntegerHelper.LeadingZeroCount(unchecked((sbyte)0xFF)));
}
+ [Fact]
+ public static void Log10Test()
+ {
+ Assert.Equal((sbyte)0, BinaryIntegerHelper.Log10((sbyte)0));
+ Assert.Equal((sbyte)0, BinaryIntegerHelper.Log10((sbyte)1));
+ Assert.Equal((sbyte)0, BinaryIntegerHelper.Log10((sbyte)9));
+ Assert.Equal((sbyte)1, BinaryIntegerHelper.Log10((sbyte)10));
+ Assert.Equal((sbyte)1, BinaryIntegerHelper.Log10((sbyte)99));
+ Assert.Equal((sbyte)2, BinaryIntegerHelper.Log10((sbyte)100));
+ Assert.Equal((sbyte)2, BinaryIntegerHelper.Log10((sbyte)127));
+ Assert.Throws(() => BinaryIntegerHelper.Log10((sbyte)(-128)));
+ Assert.Throws(() => BinaryIntegerHelper.Log10((sbyte)(-1)));
+ }
+
[Fact]
public static void PopCountTest()
{
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt128Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt128Tests.GenericMath.cs
index 8492d36367bc03..797e1e322426e7 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt128Tests.GenericMath.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt128Tests.GenericMath.cs
@@ -230,6 +230,26 @@ public static void LeadingZeroCountTest()
Assert.Equal(0x00U, BinaryIntegerHelper.LeadingZeroCount(MaxValue));
}
+ [Fact]
+ public static void Log10Test()
+ {
+ Assert.Equal(0U, BinaryIntegerHelper.Log10(Zero));
+ Assert.Equal(0U, BinaryIntegerHelper.Log10(One));
+
+ UInt128 power = 1;
+ for (uint n = 0; n < 38; n++)
+ {
+ Assert.Equal((UInt128)n, BinaryIntegerHelper.Log10(power));
+ if (power > 1)
+ {
+ Assert.Equal((UInt128)(n - 1), BinaryIntegerHelper.Log10(power - 1));
+ }
+ power *= 10;
+ }
+
+ Assert.Equal(38U, BinaryIntegerHelper.Log10(MaxValue));
+ }
+
[Fact]
public static void PopCountTest()
{
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt16Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt16Tests.GenericMath.cs
index 38d0b2ccdb6b74..4a0109d26a222b 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt16Tests.GenericMath.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt16Tests.GenericMath.cs
@@ -180,6 +180,24 @@ public static void LeadingZeroCountTest()
Assert.Equal((ushort)0x0000, BinaryIntegerHelper.LeadingZeroCount((ushort)0xFFFF));
}
+ [Fact]
+ public static void Log10Test()
+ {
+ Assert.Equal((ushort)0, BinaryIntegerHelper.Log10((ushort)0));
+ Assert.Equal((ushort)0, BinaryIntegerHelper.Log10((ushort)1));
+ Assert.Equal((ushort)0, BinaryIntegerHelper.Log10((ushort)9));
+ Assert.Equal((ushort)1, BinaryIntegerHelper.Log10((ushort)10));
+ Assert.Equal((ushort)1, BinaryIntegerHelper.Log10((ushort)99));
+ Assert.Equal((ushort)2, BinaryIntegerHelper.Log10((ushort)100));
+ Assert.Equal((ushort)2, BinaryIntegerHelper.Log10((ushort)999));
+ Assert.Equal((ushort)3, BinaryIntegerHelper.Log10((ushort)1000));
+ Assert.Equal((ushort)3, BinaryIntegerHelper.Log10((ushort)9999));
+ Assert.Equal((ushort)4, BinaryIntegerHelper.Log10((ushort)10000));
+ Assert.Equal((ushort)4, BinaryIntegerHelper.Log10((ushort)32767));
+ Assert.Equal((ushort)4, BinaryIntegerHelper.Log10((ushort)32768));
+ Assert.Equal((ushort)4, BinaryIntegerHelper.Log10((ushort)65535));
+ }
+
[Fact]
public static void PopCountTest()
{
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt32Tests.GenericMath.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt32Tests.GenericMath.cs
index b6ea65ed198988..25db7c87f97b85 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt32Tests.GenericMath.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/UInt32Tests.GenericMath.cs
@@ -181,6 +181,32 @@ public static void LeadingZeroCountTest()
Assert.Equal((uint)0x00000000, BinaryIntegerHelper.LeadingZeroCount((uint)0xFFFFFFFF));
}
+ [Fact]
+ public static void Log10Test()
+ {
+ Assert.Equal((uint)0, BinaryIntegerHelper.Log10((uint)0));
+ Assert.Equal((uint)0, BinaryIntegerHelper.Log10((uint)1));
+ Assert.Equal((uint)0, BinaryIntegerHelper