diff --git a/src/bigint.cpp b/src/bigint.cpp index 2a688debd5..64bc59e5cf 100644 --- a/src/bigint.cpp +++ b/src/bigint.cpp @@ -1259,12 +1259,11 @@ void bigint_and(BigInt *dest, const BigInt *op1, const BigInt *op2) { bigint_normalize(dest); return; } - // TODO this code path is untested - uint64_t first_digit = dest->data.digit; + dest->digit_count = max(op1->digit_count, op2->digit_count); dest->data.digits = allocate_nonzero(dest->digit_count); - dest->data.digits[0] = first_digit; - size_t i = 1; + + size_t i = 0; for (; i < op1->digit_count && i < op2->digit_count; i += 1) { dest->data.digits[i] = op1_digits[i] & op2_digits[i]; } @@ -1412,7 +1411,6 @@ void bigint_shr(BigInt *dest, const BigInt *op1, const BigInt *op2) { return; } - // TODO this code path is untested size_t digit_shift_count = shift_amt / 64; size_t leftover_shift_count = shift_amt % 64; @@ -1427,7 +1425,7 @@ void bigint_shr(BigInt *dest, const BigInt *op1, const BigInt *op2) { uint64_t digit = op1_digits[op_digit_index]; size_t dest_digit_index = op_digit_index - digit_shift_count; dest->data.digits[dest_digit_index] = carry | (digit >> leftover_shift_count); - carry = (0xffffffffffffffffULL << leftover_shift_count) & digit; + carry = digit << leftover_shift_count; if (dest_digit_index == 0) { break; } op_digit_index -= 1; diff --git a/test/cases/math.zig b/test/cases/math.zig index 47d001a590..3c33b14fbf 100644 --- a/test/cases/math.zig +++ b/test/cases/math.zig @@ -349,6 +349,23 @@ test "big number shifting" { } } +test "big number multi-limb shift and mask" { + comptime { + var a = 0xefffffffa0000001eeeeeeefaaaaaaab; + + assert(u32(a & 0xffffffff) == 0xaaaaaaab); + a >>= 32; + assert(u32(a & 0xffffffff) == 0xeeeeeeef); + a >>= 32; + assert(u32(a & 0xffffffff) == 0xa0000001); + a >>= 32; + assert(u32(a & 0xffffffff) == 0xefffffff); + a >>= 32; + + assert(a == 0); + } +} + test "xor" { test_xor(); comptime test_xor();