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 1175591a97e005..f55acb76559d63 100644 --- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs +++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs @@ -3481,42 +3481,19 @@ public static BigInteger TrailingZeroCount(BigInteger value) ulong result = 0; - if (value._sign >= 0) - { - // When the value is positive, we simply need to do a tzcnt for all bits until we find one set - - uint part = value._bits[0]; + // Both positive values and their two's-complement negative representation will share the same TrailingZeroCount, + // so the sign of value does not matter and both cases can be handled in the same way - for (int i = 1; (part == 0) && (i < value._bits.Length); i++) - { - part = value._bits[i]; - result += (sizeof(uint) * 8); + uint part = value._bits[0]; - i++; - } - - result += uint.TrailingZeroCount(part); - } - else + for (int i = 1; (part == 0) && (i < value._bits.Length); i++) { - // When the value is negative, we need to tzcnt the two's complement representation - // We'll do this "inline" to avoid needing to unnecessarily allocate. - - uint part = ~value._bits[0] + 1; - - for (int i = 1; (part == 0) && (i < value._bits.Length); i++) - { - // Simply process bits, adding the carry while the previous value is zero - - part = ~value._bits[i] + 1; - result += (sizeof(uint) * 8); - - i++; - } - - result += uint.TrailingZeroCount(part); + part = value._bits[i]; + result += (sizeof(uint) * 8); } + result += uint.TrailingZeroCount(part); + return result; } diff --git a/src/libraries/System.Runtime.Numerics/tests/BigIntegerTests.GenericMath.cs b/src/libraries/System.Runtime.Numerics/tests/BigIntegerTests.GenericMath.cs index d4e06061325aa0..3e19f1cf22e97e 100644 --- a/src/libraries/System.Runtime.Numerics/tests/BigIntegerTests.GenericMath.cs +++ b/src/libraries/System.Runtime.Numerics/tests/BigIntegerTests.GenericMath.cs @@ -366,6 +366,9 @@ public static void TrailingZeroCountTest() Assert.Equal((BigInteger)63, BinaryIntegerHelper.TrailingZeroCount(Int64MaxValuePlusOne)); Assert.Equal((BigInteger)0, BinaryIntegerHelper.TrailingZeroCount(UInt64MaxValue)); + + Assert.Equal((BigInteger)1000, BinaryIntegerHelper.TrailingZeroCount(BigInteger.Pow(2, 1000))); + Assert.Equal((BigInteger)1000, BinaryIntegerHelper.TrailingZeroCount(-BigInteger.Pow(2, 1000))); } [Fact]