authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-23 12:06:18-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-04-23 12:06:18-04:00
log89a4c373d3756baeac9d2780b1249ada37961d16
tree49ac39ac473f2e15be6670ad96856d11efdf5aa2
parent8503eff8c12697c35ab5c73d6651c4b996339706

fix bigint twos complement implementation

closes #948

2 files changed, 21 insertions(+), 0 deletions(-)

src/bigint.cpp+5
...@@ -86,6 +86,11 @@ static void to_twos_complement(BigInt *dest, const BigInt *op, size_t bit_count)...@@ -86,6 +86,11 @@ static void to_twos_complement(BigInt *dest, const BigInt *op, size_t bit_count)
86 size_t digits_to_copy = bit_count / 64;86 size_t digits_to_copy = bit_count / 64;
87 size_t leftover_bits = bit_count % 64;87 size_t leftover_bits = bit_count % 64;
88 dest->digit_count = digits_to_copy + ((leftover_bits == 0) ? 0 : 1);88 dest->digit_count = digits_to_copy + ((leftover_bits == 0) ? 0 : 1);
89 if (dest->digit_count == 1 && leftover_bits == 0) {
90 dest->data.digit = op_digits[0];
91 if (dest->data.digit == 0) dest->digit_count = 0;
92 return;
93 }
89 dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);94 dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
90 for (size_t i = 0; i < digits_to_copy; i += 1) {95 for (size_t i = 0; i < digits_to_copy; i += 1) {
91 uint64_t digit = (i < op->digit_count) ? op_digits[i] : 0;96 uint64_t digit = (i < op->digit_count) ? op_digits[i] : 0;
test/cases/eval.zig+16
...@@ -513,3 +513,19 @@ test "array concat of slices gives slice" {...@@ -513,3 +513,19 @@ test "array concat of slices gives slice" {
513 assert(std.mem.eql(u8, c, "aoeuasdf"));513 assert(std.mem.eql(u8, c, "aoeuasdf"));
514 }514 }
515}515}
516
517test "comptime shlWithOverflow" {
518 const ct_shifted: u64 = comptime amt: {
519 var amt = u64(0);
520 _ = @shlWithOverflow(u64, ~u64(0), 16, &amt);
521 break :amt amt;
522 };
523
524 const rt_shifted: u64 = amt: {
525 var amt = u64(0);
526 _ = @shlWithOverflow(u64, ~u64(0), 16, &amt);
527 break :amt amt;
528 };
529
530 assert(ct_shifted == rt_shifted);
531}