Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Simplify logic for handling negative values
  • Loading branch information
dakersnar committed Nov 2, 2022
commit 4b592208c8dd1153d837eac32fd2ed87d65f63bd
Original file line number Diff line number Diff line change
Expand Up @@ -3481,38 +3481,20 @@ 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];
// As explained in https://github.com/dotnet/runtime/issues/77720, both positive values and
// their two's-compliment negative representation will share the same TrailingZeroCount,
// so the stored sign of value does not matter

for (int i = 1; (part == 0) && (i < value._bits.Length); i++)
{
part = value._bits[i];
result += (sizeof(uint) * 8);
}
uint part = value._bits[0];

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);
}

result += uint.TrailingZeroCount(part);
part = value._bits[i];
result += (sizeof(uint) * 8);
}

result += uint.TrailingZeroCount(part);

return result;
}

Expand Down