| ... | @@ -2578,14 +2578,86 @@ test "big.int regression test for realloc with alias" { | ... | @@ -2578,14 +2578,86 @@ test "big.int regression test for realloc with alias" { |
| 2578 | } | 2578 | } |
| 2579 | | 2579 | |
| 2580 | test "big int popcount" { | 2580 | test "big int popcount" { |
| 2581 | var a = try Managed.initSet(testing.allocator, -1); | 2581 | var a = try Managed.init(testing.allocator); |
| 2582 | defer a.deinit(); | 2582 | defer a.deinit(); |
| 2583 | var b = try Managed.initSet(testing.allocator, -1); | | |
| 2584 | defer b.deinit(); | | |
| 2585 | | 2583 | |
| 2586 | try a.popCount(&b, 16); | 2584 | try a.set(0); |
| | 2585 | try popCountTest(&a, 0, 0); |
| | 2586 | try popCountTest(&a, 567, 0); |
| | 2587 | try a.set(-0); |
| | 2588 | try popCountTest(&a, 0, 0); |
| | 2589 | |
| | 2590 | try a.set(1); |
| | 2591 | try popCountTest(&a, 1, 1); |
| | 2592 | try popCountTest(&a, 13, 1); |
| | 2593 | try popCountTest(&a, 432, 1); |
| | 2594 | |
| | 2595 | try a.set(255); |
| | 2596 | try popCountTest(&a, 8, 8); |
| | 2597 | try a.set(-128); |
| | 2598 | try popCountTest(&a, 8, 1); |
| | 2599 | |
| | 2600 | try a.set(-2); |
| | 2601 | try popCountTest(&a, 16, 15); |
| | 2602 | try popCountTest(&a, 15, 14); |
| | 2603 | |
| | 2604 | try a.set(-2047); |
| | 2605 | try popCountTest(&a, 12, 2); |
| | 2606 | try popCountTest(&a, 24, 14); |
| | 2607 | |
| | 2608 | try a.set(maxInt(u5000)); |
| | 2609 | try popCountTest(&a, 5000, 5000); |
| | 2610 | try a.set(minInt(i5000)); |
| | 2611 | try popCountTest(&a, 5000, 1); |
| | 2612 | |
| | 2613 | // Check -1 at various bit counts that cross Limb size multiples. |
| | 2614 | const limb_bits = @bitSizeOf(Limb); |
| | 2615 | try a.set(-1); |
| | 2616 | try popCountTest(&a, 1, 1); // i1 |
| | 2617 | try popCountTest(&a, 2, 2); |
| | 2618 | try popCountTest(&a, 16, 16); |
| | 2619 | try popCountTest(&a, 543, 543); |
| | 2620 | try popCountTest(&a, 544, 544); |
| | 2621 | try popCountTest(&a, limb_bits - 1, limb_bits - 1); |
| | 2622 | try popCountTest(&a, limb_bits, limb_bits); |
| | 2623 | try popCountTest(&a, limb_bits + 1, limb_bits + 1); |
| | 2624 | try popCountTest(&a, limb_bits * 2 - 1, limb_bits * 2 - 1); |
| | 2625 | try popCountTest(&a, limb_bits * 2, limb_bits * 2); |
| | 2626 | try popCountTest(&a, limb_bits * 2 + 1, limb_bits * 2 + 1); |
| | 2627 | |
| | 2628 | // Check very large numbers. |
| | 2629 | try a.setString(16, "ff00000100000100" ++ ("0000000000000000" ** 62)); |
| | 2630 | try popCountTest(&a, 4032, 10); |
| | 2631 | try popCountTest(&a, 6000, 10); |
| | 2632 | a.negate(); |
| | 2633 | try popCountTest(&a, 4033, 48); |
| | 2634 | try popCountTest(&a, 4133, 148); |
| | 2635 | |
| | 2636 | // Check when most significant limb is full of 1s. |
| | 2637 | const limb_size = @bitSizeOf(Limb); |
| | 2638 | try a.set(maxInt(Limb)); |
| | 2639 | try popCountTest(&a, limb_size, limb_size); |
| | 2640 | try popCountTest(&a, limb_size + 1, limb_size); |
| | 2641 | try popCountTest(&a, limb_size * 10 + 2, limb_size); |
| | 2642 | a.negate(); |
| | 2643 | try popCountTest(&a, limb_size * 2 - 2, limb_size - 1); |
| | 2644 | try popCountTest(&a, limb_size * 2 - 1, limb_size); |
| | 2645 | try popCountTest(&a, limb_size * 2, limb_size + 1); |
| | 2646 | try popCountTest(&a, limb_size * 2 + 1, limb_size + 2); |
| | 2647 | // TODO: These produce incorrect pop count for Mutable |
| | 2648 | // https://github.com/ziglang/zig/issues/13571 |
| | 2649 | // try popCountTest(&a, limb_size * 2 + 2, limb_size + 3); |
| | 2650 | // try popCountTest(&a, limb_size * 2 + 3, limb_size + 4); |
| | 2651 | // try popCountTest(&a, limb_size * 2 + 4, limb_size + 5); |
| | 2652 | } |
| | 2653 | |
| | 2654 | fn popCountTest(val: *const Managed, bit_count: usize, expected: usize) !void { |
| | 2655 | var b = try Managed.init(testing.allocator); |
| | 2656 | defer b.deinit(); |
| | 2657 | try b.popCount(val, bit_count); |
| 2587 | | 2658 | |
| 2588 | try testing.expect(a.toConst().orderAgainstScalar(16) == .eq); | 2659 | try testing.expectEqual(std.math.Order.eq, b.toConst().orderAgainstScalar(expected)); |
| | 2660 | try testing.expectEqual(expected, val.toConst().popCount(bit_count)); |
| 2589 | } | 2661 | } |
| 2590 | | 2662 | |
| 2591 | test "big int conversion read/write twos complement" { | 2663 | test "big int conversion read/write twos complement" { |