| ... | ... | @@ -2578,14 +2578,86 @@ test "big.int regression test for realloc with alias" { |
| 2578 | 2578 | } |
| 2579 | 2579 | |
| 2580 | 2580 | test "big int popcount" { |
| 2581 | | var a = try Managed.initSet(testing.allocator, -1); |
| 2581 | var a = try Managed.init(testing.allocator); |
| 2582 | 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 | 2663 | test "big int conversion read/write twos complement" { |