| author | |
| committer | |
| log | a4e8e55908eb406f4713c22a6721d6d73f6951a5 |
| tree | d89e36d6b195dcd3862f2bc3e1f16a86384e0f1e |
| parent | 2e6125bc66bd717838fb107107564cdd66112613 |
| parent | 1d6f54cc7d6a00f3ebcc96b5265c845223c64e2e |
| signature |
Fixed bigint_xor for none negative numbers2 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 | 1271 | } |
| 1272 | 1272 | |
| 1273 | 1273 | void 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 | 1280 | if (op1->is_negative || op2->is_negative) { |
| 1275 | 1281 | // TODO this code path is untested |
| 1276 | 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 | 1295 | dest->is_negative = false; |
| 1290 | 1296 | const uint64_t *op1_digits = bigint_ptr(op1); |
| 1291 | 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 | 1301 | if (op1->digit_count == 1 && op2->digit_count == 1) { |
| 1293 | 1302 | dest->digit_count = 1; |
| 1294 | dest->data.digit = op1_digits[0] ^ op2_digits[0]; | |
| 1303 | dest->data.digit = first_digit; | |
| 1295 | 1304 | bigint_normalize(dest); |
| 1296 | 1305 | return; |
| 1297 | 1306 | } |
| 1298 | 1307 | // TODO this code path is untested |
| 1299 | uint64_t first_digit = dest->data.digit; | |
| 1300 | 1308 | dest->digit_count = max(op1->digit_count, op2->digit_count); |
| 1301 | 1309 | dest->data.digits = allocate_nonzero<uint64_t>(dest->digit_count); |
| 1302 | 1310 | dest->data.digits[0] = first_digit; |
test/cases/math.zig+27-1| ... | ... | @@ -349,6 +349,32 @@ test "big number shifting" { |
| 349 | 349 | } |
| 350 | 350 | } |
| 351 | 351 | |
| 352 | test "xor" { | |
| 353 | test_xor(); | |
| 354 | comptime test_xor(); | |
| 355 | } | |
| 356 | ||
| 357 | fn 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 | ||
| 365 | test "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 | ||
| 352 | 378 | test "f128" { |
| 353 | 379 | test_f128(); |
| 354 | 380 | comptime test_f128(); |
| ... | ... | @@ -368,4 +394,4 @@ fn test_f128() { |
| 368 | 394 | |
| 369 | 395 | fn should_not_be_zero(x: f128) { |
| 370 | 396 | assert(x != 0.0); |
| 371 | } | |
| 397 | } | |
| \ No newline at end of file |