Commit 2f11de4f51

Jacob Young <jacobly0@users.noreply.github.com>
2022-11-28 10:37:47
std.big.int.Mutable: fix set(@as(DoubleLimb, 0))
Previously, this would set len to 1 but fail to initialize any limbs.
1 parent e5d7617
Changed files (2)
lib
std
lib/std/math/big/int.zig
@@ -238,12 +238,14 @@ pub const Mutable = struct {
                     self.limbs[0] = w_value;
                 } else {
                     var i: usize = 0;
-                    while (w_value != 0) : (i += 1) {
+                    while (true) : (i += 1) {
                         self.limbs[i] = @truncate(Limb, w_value);
 
                         // TODO: shift == 64 at compile-time fails. Fails on u128 limbs.
                         w_value >>= limb_bits / 2;
                         w_value >>= limb_bits / 2;
+
+                        if (w_value == 0) break;
                     }
                 }
             },
@@ -256,11 +258,13 @@ pub const Mutable = struct {
                     const mask = (1 << limb_bits) - 1;
 
                     comptime var i = 0;
-                    inline while (w_value != 0) : (i += 1) {
+                    inline while (true) : (i += 1) {
                         self.limbs[i] = w_value & mask;
 
                         w_value >>= limb_bits / 2;
                         w_value >>= limb_bits / 2;
+
+                        if (w_value == 0) break;
                     }
                 }
             },
lib/std/math/big/int_test.zig
@@ -69,6 +69,14 @@ test "big.int set negative minimum" {
     try testing.expect((try a.to(i64)) == minInt(i64));
 }
 
+test "big.int set double-width maximum then zero" {
+    var a = try Managed.initSet(testing.allocator, maxInt(DoubleLimb));
+    defer a.deinit();
+    try a.set(@as(DoubleLimb, 0));
+
+    try testing.expectEqual(@as(DoubleLimb, 0), try a.to(DoubleLimb));
+}
+
 test "big.int to target too small error" {
     var a = try Managed.initSet(testing.allocator, 0xffffffff);
     defer a.deinit();