Commit 5c49341f09

Jacob Young <jacobly0@users.noreply.github.com>
2022-09-22 08:44:22
big.int: add support for non-comptime scalars
1 parent 7a89eeb
Changed files (2)
lib
std
lib/std/math/big/int.zig
@@ -391,7 +391,16 @@ pub const Mutable = struct {
     /// Asserts the result fits in `r`. An upper bound on the number of limbs needed by
     /// r is `math.max(a.limbs.len, calcLimbLen(scalar)) + 1`.
     pub fn addScalar(r: *Mutable, a: Const, scalar: anytype) void {
-        var limbs: [calcLimbLen(scalar)]Limb = undefined;
+        const Scalar = @TypeOf(scalar);
+        const magnitude = switch (@typeInfo(Scalar)) {
+            .ComptimeInt => scalar,
+            .Int => |int| switch (int.signedness) {
+                .signed => minInt(Scalar),
+                .unsigned => maxInt(Scalar),
+            },
+            else => @compileError("expected scalar to be an int"),
+        };
+        var limbs: [calcLimbLen(magnitude)]Limb = undefined;
         const operand = init(&limbs, scalar).toConst();
         return add(r, a, operand);
     }
@@ -2303,7 +2312,16 @@ pub const Const = struct {
 
     /// Same as `order` but the right-hand operand is a primitive integer.
     pub fn orderAgainstScalar(lhs: Const, scalar: anytype) math.Order {
-        var limbs: [calcLimbLen(scalar)]Limb = undefined;
+        const Scalar = @TypeOf(scalar);
+        const magnitude = switch (@typeInfo(Scalar)) {
+            .ComptimeInt => scalar,
+            .Int => |int| switch (int.signedness) {
+                .signed => minInt(Scalar),
+                .unsigned => maxInt(Scalar),
+            },
+            else => @compileError("expected scalar to be an int"),
+        };
+        var limbs: [calcLimbLen(magnitude)]Limb = undefined;
         const rhs = Mutable.init(&limbs, scalar);
         return order(lhs, rhs.toConst());
     }
lib/std/math/big/int_test.zig
@@ -573,7 +573,7 @@ test "big.int add sign" {
     try testing.expect((try a.to(i32)) == -3);
 }
 
-test "big.int add scalar" {
+test "big.int add comptime scalar" {
     var a = try Managed.initSet(testing.allocator, 50);
     defer a.deinit();
 
@@ -584,6 +584,17 @@ test "big.int add scalar" {
     try testing.expect((try b.to(u32)) == 55);
 }
 
+test "big.int add scalar" {
+    var a = try Managed.initSet(testing.allocator, 123);
+    defer a.deinit();
+
+    var b = try Managed.init(testing.allocator);
+    defer b.deinit();
+    try b.addScalar(&a, @as(u32, 31));
+
+    try testing.expect((try b.to(u32)) == 154);
+}
+
 test "big.int addWrap single-single, unsigned" {
     var a = try Managed.initSet(testing.allocator, maxInt(u17));
     defer a.deinit();