big.int: add support for non-comptime scalars

This commit is contained in:
Jacob Young 2022-09-22 02:44:22 -04:00
parent 7a89eebfc6
commit 5c49341f09
2 changed files with 32 additions and 3 deletions

View File

@ -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());
}

View File

@ -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();