authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-24 15:44:45-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-24 16:31:22-04:00
log4241cd666dbf5117a6c32357c091ca3bc7a0fcd0
tree8c9fcb5ff796a2d05c63e2d5b890b3092c5af614
parent877036e7ef37432579233347b5b3cfce66040f83
signaturelock-open Commit is signed but in an unrecognized format.

fix more bigint code paths and add tests


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

src/bigint.cpp+10-21
...@@ -50,7 +50,7 @@ size_t bigint_bits_needed(const BigInt *op) {...@@ -50,7 +50,7 @@ size_t bigint_bits_needed(const BigInt *op) {
50 size_t full_bits = op->digit_count * 64;50 size_t full_bits = op->digit_count * 64;
51 size_t leading_zero_count = bigint_clz(op, full_bits);51 size_t leading_zero_count = bigint_clz(op, full_bits);
52 size_t bits_needed = full_bits - leading_zero_count;52 size_t bits_needed = full_bits - leading_zero_count;
53 return bits_needed;53 return bits_needed + op->is_negative;
54}54}
5555
56static void to_twos_complement(BigInt *dest, const BigInt *op, size_t bit_count) {56static void to_twos_complement(BigInt *dest, const BigInt *op, size_t bit_count) {
...@@ -1188,7 +1188,6 @@ void bigint_or(BigInt *dest, const BigInt *op1, const BigInt *op2) {...@@ -1188,7 +1188,6 @@ void bigint_or(BigInt *dest, const BigInt *op1, const BigInt *op2) {
1188 return bigint_init_bigint(dest, op1);1188 return bigint_init_bigint(dest, op1);
1189 }1189 }
1190 if (op1->is_negative || op2->is_negative) {1190 if (op1->is_negative || op2->is_negative) {
1191 // TODO this code path is untested
1192 size_t big_bit_count = max(bigint_bits_needed(op1), bigint_bits_needed(op2));1191 size_t big_bit_count = max(bigint_bits_needed(op1), bigint_bits_needed(op2));
11931192
1194 BigInt twos_comp_op1 = {0};1193 BigInt twos_comp_op1 = {0};
...@@ -1211,13 +1210,9 @@ void bigint_or(BigInt *dest, const BigInt *op1, const BigInt *op2) {...@@ -1211,13 +1210,9 @@ void bigint_or(BigInt *dest, const BigInt *op1, const BigInt *op2) {
1211 bigint_normalize(dest);1210 bigint_normalize(dest);
1212 return;1211 return;
1213 }1212 }
1214 // TODO this code path is untested
1215 uint64_t first_digit = dest->data.digit;
1216 dest->digit_count = max(op1->digit_count, op2->digit_count);1213 dest->digit_count = max(op1->digit_count, op2->digit_count);
1217 dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);1214 dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
1218 dest->data.digits[0] = first_digit;1215 for (size_t i = 0; i < dest->digit_count; i += 1) {
1219 size_t i = 1;
1220 for (; i < dest->digit_count; i += 1) {
1221 uint64_t digit = 0;1216 uint64_t digit = 0;
1222 if (i < op1->digit_count) {1217 if (i < op1->digit_count) {
1223 digit |= op1_digits[i];1218 digit |= op1_digits[i];
...@@ -1236,7 +1231,6 @@ void bigint_and(BigInt *dest, const BigInt *op1, const BigInt *op2) {...@@ -1236,7 +1231,6 @@ void bigint_and(BigInt *dest, const BigInt *op1, const BigInt *op2) {
1236 return bigint_init_unsigned(dest, 0);1231 return bigint_init_unsigned(dest, 0);
1237 }1232 }
1238 if (op1->is_negative || op2->is_negative) {1233 if (op1->is_negative || op2->is_negative) {
1239 // TODO this code path is untested
1240 size_t big_bit_count = max(bigint_bits_needed(op1), bigint_bits_needed(op2));1234 size_t big_bit_count = max(bigint_bits_needed(op1), bigint_bits_needed(op2));
12411235
1242 BigInt twos_comp_op1 = {0};1236 BigInt twos_comp_op1 = {0};
...@@ -1282,7 +1276,6 @@ void bigint_xor(BigInt *dest, const BigInt *op1, const BigInt *op2) {...@@ -1282,7 +1276,6 @@ void bigint_xor(BigInt *dest, const BigInt *op1, const BigInt *op2) {
1282 return bigint_init_bigint(dest, op1);1276 return bigint_init_bigint(dest, op1);
1283 }1277 }
1284 if (op1->is_negative || op2->is_negative) {1278 if (op1->is_negative || op2->is_negative) {
1285 // TODO this code path is untested
1286 size_t big_bit_count = max(bigint_bits_needed(op1), bigint_bits_needed(op2));1279 size_t big_bit_count = max(bigint_bits_needed(op1), bigint_bits_needed(op2));
12871280
1288 BigInt twos_comp_op1 = {0};1281 BigInt twos_comp_op1 = {0};
...@@ -1301,27 +1294,25 @@ void bigint_xor(BigInt *dest, const BigInt *op1, const BigInt *op2) {...@@ -1301,27 +1294,25 @@ void bigint_xor(BigInt *dest, const BigInt *op1, const BigInt *op2) {
1301 const uint64_t *op2_digits = bigint_ptr(op2);1294 const uint64_t *op2_digits = bigint_ptr(op2);
13021295
1303 assert(op1->digit_count > 0 && op2->digit_count > 0);1296 assert(op1->digit_count > 0 && op2->digit_count > 0);
1304 uint64_t first_digit = op1_digits[0] ^ op2_digits[0];
1305 if (op1->digit_count == 1 && op2->digit_count == 1) {1297 if (op1->digit_count == 1 && op2->digit_count == 1) {
1306 dest->digit_count = 1;1298 dest->digit_count = 1;
1307 dest->data.digit = first_digit;1299 dest->data.digit = op1_digits[0] ^ op2_digits[0];
1308 bigint_normalize(dest);1300 bigint_normalize(dest);
1309 return;1301 return;
1310 }1302 }
1311 // TODO this code path is untested
1312 dest->digit_count = max(op1->digit_count, op2->digit_count);1303 dest->digit_count = max(op1->digit_count, op2->digit_count);
1313 dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);1304 dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
1314 dest->data.digits[0] = first_digit;1305 size_t i = 0;
1315 size_t i = 1;
1316 for (; i < op1->digit_count && i < op2->digit_count; i += 1) {1306 for (; i < op1->digit_count && i < op2->digit_count; i += 1) {
1317 dest->data.digits[i] = op1_digits[i] ^ op2_digits[i];1307 dest->data.digits[i] = op1_digits[i] ^ op2_digits[i];
1318 }1308 }
1319 for (; i < dest->digit_count; i += 1) {1309 for (; i < dest->digit_count; i += 1) {
1320 if (i < op1->digit_count) {1310 if (i < op1->digit_count) {
1321 dest->data.digits[i] = op1_digits[i];1311 dest->data.digits[i] = op1_digits[i];
1322 }1312 } else if (i < op2->digit_count) {
1323 if (i < op2->digit_count) {
1324 dest->data.digits[i] = op2_digits[i];1313 dest->data.digits[i] = op2_digits[i];
1314 } else {
1315 zig_unreachable();
1325 }1316 }
1326 }1317 }
1327 bigint_normalize(dest);1318 bigint_normalize(dest);
...@@ -1485,8 +1476,7 @@ void bigint_not(BigInt *dest, const BigInt *op, size_t bit_count, bool is_signed...@@ -1485,8 +1476,7 @@ void bigint_not(BigInt *dest, const BigInt *op, size_t bit_count, bool is_signed
1485 bigint_normalize(dest);1476 bigint_normalize(dest);
1486 return;1477 return;
1487 }1478 }
1488 // TODO this code path is untested1479 dest->digit_count = (bit_count + 63) / 64;
1489 dest->digit_count = bit_count / 64;
1490 assert(dest->digit_count >= op->digit_count);1480 assert(dest->digit_count >= op->digit_count);
1491 dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);1481 dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
1492 size_t i = 0;1482 size_t i = 0;
...@@ -1496,9 +1486,9 @@ void bigint_not(BigInt *dest, const BigInt *op, size_t bit_count, bool is_signed...@@ -1496,9 +1486,9 @@ void bigint_not(BigInt *dest, const BigInt *op, size_t bit_count, bool is_signed
1496 for (; i < dest->digit_count; i += 1) {1486 for (; i < dest->digit_count; i += 1) {
1497 dest->data.digits[i] = 0xffffffffffffffffULL;1487 dest->data.digits[i] = 0xffffffffffffffffULL;
1498 }1488 }
1499 size_t digit_index = dest->digit_count - (bit_count / 64) - 1;1489 size_t digit_index = dest->digit_count - 1;
1500 size_t digit_bit_index = bit_count % 64;1490 size_t digit_bit_index = bit_count % 64;
1501 if (digit_index < dest->digit_count) {1491 if (digit_bit_index != 0) {
1502 uint64_t mask = (1ULL << digit_bit_index) - 1;1492 uint64_t mask = (1ULL << digit_bit_index) - 1;
1503 dest->data.digits[digit_index] &= mask;1493 dest->data.digits[digit_index] &= mask;
1504 }1494 }
...@@ -1555,7 +1545,6 @@ void bigint_append_buf(Buf *buf, const BigInt *op, uint64_t base) {...@@ -1555,7 +1545,6 @@ void bigint_append_buf(Buf *buf, const BigInt *op, uint64_t base) {
1555 buf_appendf(buf, "%" ZIG_PRI_u64, op->data.digit);1545 buf_appendf(buf, "%" ZIG_PRI_u64, op->data.digit);
1556 return;1546 return;
1557 }1547 }
1558 // TODO this code path is untested
1559 size_t first_digit_index = buf_len(buf);1548 size_t first_digit_index = buf_len(buf);
15601549
1561 BigInt digit_bi = {0};1550 BigInt digit_bi = {0};
test/cases/eval.zig+4
...@@ -746,7 +746,11 @@ test "comptime bitwise operators" {...@@ -746,7 +746,11 @@ test "comptime bitwise operators" {
746 assert(3 | -1 == -1);746 assert(3 | -1 == -1);
747 assert(-3 | -1 == -1);747 assert(-3 | -1 == -1);
748 assert(3 ^ -1 == -4);748 assert(3 ^ -1 == -4);
749 assert(-3 ^ -1 == 2);
749 assert(~i8(-1) == 0);750 assert(~i8(-1) == 0);
750 assert(~i128(-1) == 0);751 assert(~i128(-1) == 0);
752 assert(18446744073709551615 & 18446744073709551611 == 18446744073709551611);
753 assert(-18446744073709551615 & -18446744073709551611 == -18446744073709551615);
754 assert(~u128(0) == 0xffffffffffffffffffffffffffffffff);
751 }755 }
752}756}