From 89a4c373d3756baeac9d2780b1249ada37961d16 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 23 Apr 2018 12:06:18 -0400 Subject: [PATCH] fix bigint twos complement implementation closes #948 --- src/bigint.cpp | 5 +++++ test/cases/eval.zig | 16 ++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/bigint.cpp b/src/bigint.cpp index 85e5dad4ad8a49f669fb7095d2c3f3a54a75a040..2a688debd55eda49171839681a8a154ec303f6a4 100644 --- a/src/bigint.cpp +++ b/src/bigint.cpp @@ -86,6 +86,11 @@ static void to_twos_complement(BigInt *dest, const BigInt *op, size_t bit_count) size_t digits_to_copy = bit_count / 64; size_t leftover_bits = bit_count % 64; dest->digit_count = digits_to_copy + ((leftover_bits == 0) ? 0 : 1); + if (dest->digit_count == 1 && leftover_bits == 0) { + dest->data.digit = op_digits[0]; + if (dest->data.digit == 0) dest->digit_count = 0; + return; + } dest->data.digits = allocate_nonzero(dest->digit_count); for (size_t i = 0; i < digits_to_copy; i += 1) { uint64_t digit = (i < op->digit_count) ? op_digits[i] : 0; diff --git a/test/cases/eval.zig b/test/cases/eval.zig index d6f7afe8644ecf62f39339d5d254d29bd29ecdc9..e13d4340e719f0badcafbf9cebad3a0f8655b199 100644 --- a/test/cases/eval.zig +++ b/test/cases/eval.zig @@ -513,3 +513,19 @@ test "array concat of slices gives slice" { assert(std.mem.eql(u8, c, "aoeuasdf")); } } + +test "comptime shlWithOverflow" { + const ct_shifted: u64 = comptime amt: { + var amt = u64(0); + _ = @shlWithOverflow(u64, ~u64(0), 16, &amt); + break :amt amt; + }; + + const rt_shifted: u64 = amt: { + var amt = u64(0); + _ = @shlWithOverflow(u64, ~u64(0), 16, &amt); + break :amt amt; + }; + + assert(ct_shifted == rt_shifted); +} -- 2.54.0