| Index: runtime/vm/bigint_operations.cc
|
| diff --git a/runtime/vm/bigint_operations.cc b/runtime/vm/bigint_operations.cc
|
| index 7fba196e17bbb3573b825f9603dba63b86a15ed6..b7c7a69ff6ff2ea7e4b2e4c1b6ab191066b233eb 100644
|
| --- a/runtime/vm/bigint_operations.cc
|
| +++ b/runtime/vm/bigint_operations.cc
|
| @@ -1291,6 +1291,34 @@ RawBigint* BigintOperations::BitNot(const Bigint& bigint) {
|
| }
|
|
|
|
|
| +int64_t BigintOperations::BitLength(const Bigint& bigint) {
|
| + ASSERT(IsClamped(bigint));
|
| + intptr_t length = bigint.Length();
|
| + if (length == 0) return 0;
|
| + intptr_t last = length - 1;
|
| +
|
| + Chunk high_chunk = bigint.GetChunkAt(last);
|
| + ASSERT(high_chunk != 0);
|
| + int64_t bit_length =
|
| + static_cast<int64_t>(kDigitBitSize) * last + CountBits(high_chunk);
|
| +
|
| + if (bigint.IsNegative()) {
|
| + // We are calculating the 2's complement bitlength but we have a sign and
|
| + // magnitude representation. The length is the same except when the
|
| + // magnitude is an exact power of two, 2^k. In 2's complement format,
|
| + // -(2^k) takes one fewer bit than (2^k).
|
| +
|
| + if ((high_chunk & (high_chunk - 1)) == 0) { // Single bit set?
|
| + for (intptr_t i = 0; i < last; i++) {
|
| + if (bigint.GetChunkAt(i) != 0) return bit_length;
|
| + }
|
| + bit_length -= 1;
|
| + }
|
| + }
|
| + return bit_length;
|
| +}
|
| +
|
| +
|
| int BigintOperations::Compare(const Bigint& a, const Bigint& b) {
|
| bool a_is_negative = a.IsNegative();
|
| bool b_is_negative = b.IsNegative();
|
|
|