authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-17 10:24:27-05:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2018-01-17 10:24:27-05:00
loga4e8e55908eb406f4713c22a6721d6d73f6951a5
treed89e36d6b195dcd3862f2bc3e1f16a86384e0f1e
parent2e6125bc66bd717838fb107107564cdd66112613
parent1d6f54cc7d6a00f3ebcc96b5265c845223c64e2e
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #701 from Hejsil/fix-xor-with-zero

Fixed bigint_xor for none negative numbers

2 files changed, 37 insertions(+), 3 deletions(-)

src/bigint.cpp+10-2
...@@ -1271,6 +1271,12 @@ void bigint_and(BigInt *dest, const BigInt *op1, const BigInt *op2) {...@@ -1271,6 +1271,12 @@ void bigint_and(BigInt *dest, const BigInt *op1, const BigInt *op2) {
1271}1271}
12721272
1273void bigint_xor(BigInt *dest, const BigInt *op1, const BigInt *op2) {1273void bigint_xor(BigInt *dest, const BigInt *op1, const BigInt *op2) {
1274 if (op1->digit_count == 0) {
1275 return bigint_init_bigint(dest, op2);
1276 }
1277 if (op2->digit_count == 0) {
1278 return bigint_init_bigint(dest, op1);
1279 }
1274 if (op1->is_negative || op2->is_negative) {1280 if (op1->is_negative || op2->is_negative) {
1275 // TODO this code path is untested1281 // TODO this code path is untested
1276 size_t big_bit_count = max(bigint_bits_needed(op1), bigint_bits_needed(op2));1282 size_t big_bit_count = max(bigint_bits_needed(op1), bigint_bits_needed(op2));
...@@ -1289,14 +1295,16 @@ void bigint_xor(BigInt *dest, const BigInt *op1, const BigInt *op2) {...@@ -1289,14 +1295,16 @@ void bigint_xor(BigInt *dest, const BigInt *op1, const BigInt *op2) {
1289 dest->is_negative = false;1295 dest->is_negative = false;
1290 const uint64_t *op1_digits = bigint_ptr(op1);1296 const uint64_t *op1_digits = bigint_ptr(op1);
1291 const uint64_t *op2_digits = bigint_ptr(op2);1297 const uint64_t *op2_digits = bigint_ptr(op2);
1298
1299 assert(op1->digit_count > 0 && op2->digit_count > 0);
1300 uint64_t first_digit = op1_digits[0] ^ op2_digits[0];
1292 if (op1->digit_count == 1 && op2->digit_count == 1) {1301 if (op1->digit_count == 1 && op2->digit_count == 1) {
1293 dest->digit_count = 1;1302 dest->digit_count = 1;
1294 dest->data.digit = op1_digits[0] ^ op2_digits[0];1303 dest->data.digit = first_digit;
1295 bigint_normalize(dest);1304 bigint_normalize(dest);
1296 return;1305 return;
1297 }1306 }
1298 // TODO this code path is untested1307 // TODO this code path is untested
1299 uint64_t first_digit = dest->data.digit;
1300 dest->digit_count = max(op1->digit_count, op2->digit_count);1308 dest->digit_count = max(op1->digit_count, op2->digit_count);
1301 dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);1309 dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count);
1302 dest->data.digits[0] = first_digit;1310 dest->data.digits[0] = first_digit;
test/cases/math.zig+27-1
...@@ -349,6 +349,32 @@ test "big number shifting" {...@@ -349,6 +349,32 @@ test "big number shifting" {
349 }349 }
350}350}
351351
352test "xor" {
353 test_xor();
354 comptime test_xor();
355}
356
357fn test_xor() {
358 assert(0xFF ^ 0x00 == 0xFF);
359 assert(0xF0 ^ 0x0F == 0xFF);
360 assert(0xFF ^ 0xF0 == 0x0F);
361 assert(0xFF ^ 0x0F == 0xF0);
362 assert(0xFF ^ 0xFF == 0x00);
363}
364
365test "big number xor" {
366 comptime {
367 assert(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0x00000000000000000000000000000000 == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
368 assert(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0x0000000000000000FFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
369 assert(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x0000000000000000FFFFFFFFFFFFFFFF);
370 assert(0x0000000000000000FFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFF0000000000000000);
371 assert(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000000000000000000000000000);
372 assert(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0x00000000FFFFFFFF00000000FFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
373 assert(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000FFFFFFFF00000000FFFFFFFF);
374 assert(0x00000000FFFFFFFF00000000FFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFF00000000FFFFFFFF00000000);
375 }
376}
377
352test "f128" {378test "f128" {
353 test_f128();379 test_f128();
354 comptime test_f128();380 comptime test_f128();
...@@ -368,4 +394,4 @@ fn test_f128() {...@@ -368,4 +394,4 @@ fn test_f128() {
368394
369fn should_not_be_zero(x: f128) {395fn should_not_be_zero(x: f128) {
370 assert(x != 0.0);396 assert(x != 0.0);
371}397}
\ No newline at end of file