mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
This function can be used to initialize a big integer to either the upper or lower limit of a 2s-complement integer. Note that the result is still in sign-magnitude representation, though in order to convert it into twos complement all one has to do is take the absolute value.
1838 lines
57 KiB
Zig
1838 lines
57 KiB
Zig
const std = @import("../../std.zig");
|
|
const mem = std.mem;
|
|
const testing = std.testing;
|
|
const Managed = std.math.big.int.Managed;
|
|
const Mutable = std.math.big.int.Mutable;
|
|
const Limb = std.math.big.Limb;
|
|
const DoubleLimb = std.math.big.DoubleLimb;
|
|
const SignedDoubleLimb = std.math.big.SignedDoubleLimb;
|
|
const maxInt = std.math.maxInt;
|
|
const minInt = std.math.minInt;
|
|
|
|
// NOTE: All the following tests assume the max machine-word will be 64-bit.
|
|
//
|
|
// They will still run on larger than this and should pass, but the multi-limb code-paths
|
|
// may be untested in some cases.
|
|
|
|
test "big.int comptime_int set" {
|
|
comptime var s = 0xefffffff00000001eeeeeeefaaaaaaab;
|
|
var a = try Managed.initSet(testing.allocator, s);
|
|
defer a.deinit();
|
|
|
|
const s_limb_count = 128 / @typeInfo(Limb).Int.bits;
|
|
|
|
comptime var i: usize = 0;
|
|
inline while (i < s_limb_count) : (i += 1) {
|
|
const result = @as(Limb, s & maxInt(Limb));
|
|
s >>= @typeInfo(Limb).Int.bits / 2;
|
|
s >>= @typeInfo(Limb).Int.bits / 2;
|
|
try testing.expect(a.limbs[i] == result);
|
|
}
|
|
}
|
|
|
|
test "big.int comptime_int set negative" {
|
|
var a = try Managed.initSet(testing.allocator, -10);
|
|
defer a.deinit();
|
|
|
|
try testing.expect(a.limbs[0] == 10);
|
|
try testing.expect(a.isPositive() == false);
|
|
}
|
|
|
|
test "big.int int set unaligned small" {
|
|
var a = try Managed.initSet(testing.allocator, @as(u7, 45));
|
|
defer a.deinit();
|
|
|
|
try testing.expect(a.limbs[0] == 45);
|
|
try testing.expect(a.isPositive() == true);
|
|
}
|
|
|
|
test "big.int comptime_int to" {
|
|
var a = try Managed.initSet(testing.allocator, 0xefffffff00000001eeeeeeefaaaaaaab);
|
|
defer a.deinit();
|
|
|
|
try testing.expect((try a.to(u128)) == 0xefffffff00000001eeeeeeefaaaaaaab);
|
|
}
|
|
|
|
test "big.int sub-limb to" {
|
|
var a = try Managed.initSet(testing.allocator, 10);
|
|
defer a.deinit();
|
|
|
|
try testing.expect((try a.to(u8)) == 10);
|
|
}
|
|
|
|
test "big.int to target too small error" {
|
|
var a = try Managed.initSet(testing.allocator, 0xffffffff);
|
|
defer a.deinit();
|
|
|
|
try testing.expectError(error.TargetTooSmall, a.to(u8));
|
|
}
|
|
|
|
test "big.int normalize" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
try a.ensureCapacity(8);
|
|
|
|
a.limbs[0] = 1;
|
|
a.limbs[1] = 2;
|
|
a.limbs[2] = 3;
|
|
a.limbs[3] = 0;
|
|
a.normalize(4);
|
|
try testing.expect(a.len() == 3);
|
|
|
|
a.limbs[0] = 1;
|
|
a.limbs[1] = 2;
|
|
a.limbs[2] = 3;
|
|
a.normalize(3);
|
|
try testing.expect(a.len() == 3);
|
|
|
|
a.limbs[0] = 0;
|
|
a.limbs[1] = 0;
|
|
a.normalize(2);
|
|
try testing.expect(a.len() == 1);
|
|
|
|
a.limbs[0] = 0;
|
|
a.normalize(1);
|
|
try testing.expect(a.len() == 1);
|
|
}
|
|
|
|
test "big.int normalize multi" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
try a.ensureCapacity(8);
|
|
|
|
a.limbs[0] = 1;
|
|
a.limbs[1] = 2;
|
|
a.limbs[2] = 0;
|
|
a.limbs[3] = 0;
|
|
a.normalize(4);
|
|
try testing.expect(a.len() == 2);
|
|
|
|
a.limbs[0] = 1;
|
|
a.limbs[1] = 2;
|
|
a.limbs[2] = 3;
|
|
a.normalize(3);
|
|
try testing.expect(a.len() == 3);
|
|
|
|
a.limbs[0] = 0;
|
|
a.limbs[1] = 0;
|
|
a.limbs[2] = 0;
|
|
a.limbs[3] = 0;
|
|
a.normalize(4);
|
|
try testing.expect(a.len() == 1);
|
|
|
|
a.limbs[0] = 0;
|
|
a.normalize(1);
|
|
try testing.expect(a.len() == 1);
|
|
}
|
|
|
|
test "big.int parity" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
|
|
try a.set(0);
|
|
try testing.expect(a.isEven());
|
|
try testing.expect(!a.isOdd());
|
|
|
|
try a.set(7);
|
|
try testing.expect(!a.isEven());
|
|
try testing.expect(a.isOdd());
|
|
}
|
|
|
|
test "big.int bitcount + sizeInBaseUpperBound" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
|
|
try a.set(0b100);
|
|
try testing.expect(a.bitCountAbs() == 3);
|
|
try testing.expect(a.sizeInBaseUpperBound(2) >= 3);
|
|
try testing.expect(a.sizeInBaseUpperBound(10) >= 1);
|
|
|
|
a.negate();
|
|
try testing.expect(a.bitCountAbs() == 3);
|
|
try testing.expect(a.sizeInBaseUpperBound(2) >= 4);
|
|
try testing.expect(a.sizeInBaseUpperBound(10) >= 2);
|
|
|
|
try a.set(0xffffffff);
|
|
try testing.expect(a.bitCountAbs() == 32);
|
|
try testing.expect(a.sizeInBaseUpperBound(2) >= 32);
|
|
try testing.expect(a.sizeInBaseUpperBound(10) >= 10);
|
|
|
|
try a.shiftLeft(a, 5000);
|
|
try testing.expect(a.bitCountAbs() == 5032);
|
|
try testing.expect(a.sizeInBaseUpperBound(2) >= 5032);
|
|
a.setSign(false);
|
|
|
|
try testing.expect(a.bitCountAbs() == 5032);
|
|
try testing.expect(a.sizeInBaseUpperBound(2) >= 5033);
|
|
}
|
|
|
|
test "big.int bitcount/to" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
|
|
try a.set(0);
|
|
try testing.expect(a.bitCountTwosComp() == 0);
|
|
|
|
try testing.expect((try a.to(u0)) == 0);
|
|
try testing.expect((try a.to(i0)) == 0);
|
|
|
|
try a.set(-1);
|
|
try testing.expect(a.bitCountTwosComp() == 1);
|
|
try testing.expect((try a.to(i1)) == -1);
|
|
|
|
try a.set(-8);
|
|
try testing.expect(a.bitCountTwosComp() == 4);
|
|
try testing.expect((try a.to(i4)) == -8);
|
|
|
|
try a.set(127);
|
|
try testing.expect(a.bitCountTwosComp() == 7);
|
|
try testing.expect((try a.to(u7)) == 127);
|
|
|
|
try a.set(-128);
|
|
try testing.expect(a.bitCountTwosComp() == 8);
|
|
try testing.expect((try a.to(i8)) == -128);
|
|
|
|
try a.set(-129);
|
|
try testing.expect(a.bitCountTwosComp() == 9);
|
|
try testing.expect((try a.to(i9)) == -129);
|
|
}
|
|
|
|
test "big.int fits" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
|
|
try a.set(0);
|
|
try testing.expect(a.fits(u0));
|
|
try testing.expect(a.fits(i0));
|
|
|
|
try a.set(255);
|
|
try testing.expect(!a.fits(u0));
|
|
try testing.expect(!a.fits(u1));
|
|
try testing.expect(!a.fits(i8));
|
|
try testing.expect(a.fits(u8));
|
|
try testing.expect(a.fits(u9));
|
|
try testing.expect(a.fits(i9));
|
|
|
|
try a.set(-128);
|
|
try testing.expect(!a.fits(i7));
|
|
try testing.expect(a.fits(i8));
|
|
try testing.expect(a.fits(i9));
|
|
try testing.expect(!a.fits(u9));
|
|
|
|
try a.set(0x1ffffffffeeeeeeee);
|
|
try testing.expect(!a.fits(u32));
|
|
try testing.expect(!a.fits(u64));
|
|
try testing.expect(a.fits(u65));
|
|
}
|
|
|
|
test "big.int string set" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
|
|
try a.setString(10, "120317241209124781241290847124");
|
|
try testing.expect((try a.to(u128)) == 120317241209124781241290847124);
|
|
}
|
|
|
|
test "big.int string negative" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
|
|
try a.setString(10, "-1023");
|
|
try testing.expect((try a.to(i32)) == -1023);
|
|
}
|
|
|
|
test "big.int string set number with underscores" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
|
|
try a.setString(10, "__1_2_0_3_1_7_2_4_1_2_0_____9_1__2__4_7_8_1_2_4_1_2_9_0_8_4_7_1_2_4___");
|
|
try testing.expect((try a.to(u128)) == 120317241209124781241290847124);
|
|
}
|
|
|
|
test "big.int string set case insensitive number" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
|
|
try a.setString(16, "aB_cD_eF");
|
|
try testing.expect((try a.to(u32)) == 0xabcdef);
|
|
}
|
|
|
|
test "big.int string set bad char error" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
try testing.expectError(error.InvalidCharacter, a.setString(10, "x"));
|
|
}
|
|
|
|
test "big.int string set bad base error" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
try testing.expectError(error.InvalidBase, a.setString(45, "10"));
|
|
}
|
|
|
|
test "big.int twos complement limit set" {
|
|
const test_types = [_]type{
|
|
u64,
|
|
i64,
|
|
u1,
|
|
i1,
|
|
u0,
|
|
i0,
|
|
u65,
|
|
i65,
|
|
};
|
|
|
|
inline for (test_types) |T| {
|
|
// To work around 'control flow attempts to use compile-time variable at runtime'
|
|
const U = T;
|
|
const int_info = @typeInfo(U).Int;
|
|
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
|
|
try a.setTwosCompIntLimit(.max, int_info.signedness, int_info.bits);
|
|
var max: U = maxInt(U);
|
|
try testing.expect(max == try a.to(U));
|
|
|
|
try a.setTwosCompIntLimit(.min, int_info.signedness, int_info.bits);
|
|
var min: U = minInt(U);
|
|
try testing.expect(min == try a.to(U));
|
|
}
|
|
}
|
|
|
|
test "big.int string to" {
|
|
var a = try Managed.initSet(testing.allocator, 120317241209124781241290847124);
|
|
defer a.deinit();
|
|
|
|
const as = try a.toString(testing.allocator, 10, .lower);
|
|
defer testing.allocator.free(as);
|
|
const es = "120317241209124781241290847124";
|
|
|
|
try testing.expect(mem.eql(u8, as, es));
|
|
}
|
|
|
|
test "big.int string to base base error" {
|
|
var a = try Managed.initSet(testing.allocator, 0xffffffff);
|
|
defer a.deinit();
|
|
|
|
try testing.expectError(error.InvalidBase, a.toString(testing.allocator, 45, .lower));
|
|
}
|
|
|
|
test "big.int string to base 2" {
|
|
var a = try Managed.initSet(testing.allocator, -0b1011);
|
|
defer a.deinit();
|
|
|
|
const as = try a.toString(testing.allocator, 2, .lower);
|
|
defer testing.allocator.free(as);
|
|
const es = "-1011";
|
|
|
|
try testing.expect(mem.eql(u8, as, es));
|
|
}
|
|
|
|
test "big.int string to base 16" {
|
|
var a = try Managed.initSet(testing.allocator, 0xefffffff00000001eeeeeeefaaaaaaab);
|
|
defer a.deinit();
|
|
|
|
const as = try a.toString(testing.allocator, 16, .lower);
|
|
defer testing.allocator.free(as);
|
|
const es = "efffffff00000001eeeeeeefaaaaaaab";
|
|
|
|
try testing.expect(mem.eql(u8, as, es));
|
|
}
|
|
|
|
test "big.int neg string to" {
|
|
var a = try Managed.initSet(testing.allocator, -123907434);
|
|
defer a.deinit();
|
|
|
|
const as = try a.toString(testing.allocator, 10, .lower);
|
|
defer testing.allocator.free(as);
|
|
const es = "-123907434";
|
|
|
|
try testing.expect(mem.eql(u8, as, es));
|
|
}
|
|
|
|
test "big.int zero string to" {
|
|
var a = try Managed.initSet(testing.allocator, 0);
|
|
defer a.deinit();
|
|
|
|
const as = try a.toString(testing.allocator, 10, .lower);
|
|
defer testing.allocator.free(as);
|
|
const es = "0";
|
|
|
|
try testing.expect(mem.eql(u8, as, es));
|
|
}
|
|
|
|
test "big.int clone" {
|
|
var a = try Managed.initSet(testing.allocator, 1234);
|
|
defer a.deinit();
|
|
var b = try a.clone();
|
|
defer b.deinit();
|
|
|
|
try testing.expect((try a.to(u32)) == 1234);
|
|
try testing.expect((try b.to(u32)) == 1234);
|
|
|
|
try a.set(77);
|
|
try testing.expect((try a.to(u32)) == 77);
|
|
try testing.expect((try b.to(u32)) == 1234);
|
|
}
|
|
|
|
test "big.int swap" {
|
|
var a = try Managed.initSet(testing.allocator, 1234);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 5678);
|
|
defer b.deinit();
|
|
|
|
try testing.expect((try a.to(u32)) == 1234);
|
|
try testing.expect((try b.to(u32)) == 5678);
|
|
|
|
a.swap(&b);
|
|
|
|
try testing.expect((try a.to(u32)) == 5678);
|
|
try testing.expect((try b.to(u32)) == 1234);
|
|
}
|
|
|
|
test "big.int to negative" {
|
|
var a = try Managed.initSet(testing.allocator, -10);
|
|
defer a.deinit();
|
|
|
|
try testing.expect((try a.to(i32)) == -10);
|
|
}
|
|
|
|
test "big.int compare" {
|
|
var a = try Managed.initSet(testing.allocator, -11);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 10);
|
|
defer b.deinit();
|
|
|
|
try testing.expect(a.orderAbs(b) == .gt);
|
|
try testing.expect(a.order(b) == .lt);
|
|
}
|
|
|
|
test "big.int compare similar" {
|
|
var a = try Managed.initSet(testing.allocator, 0xffffffffeeeeeeeeffffffffeeeeeeee);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0xffffffffeeeeeeeeffffffffeeeeeeef);
|
|
defer b.deinit();
|
|
|
|
try testing.expect(a.orderAbs(b) == .lt);
|
|
try testing.expect(b.orderAbs(a) == .gt);
|
|
}
|
|
|
|
test "big.int compare different limb size" {
|
|
var a = try Managed.initSet(testing.allocator, maxInt(Limb) + 1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 1);
|
|
defer b.deinit();
|
|
|
|
try testing.expect(a.orderAbs(b) == .gt);
|
|
try testing.expect(b.orderAbs(a) == .lt);
|
|
}
|
|
|
|
test "big.int compare multi-limb" {
|
|
var a = try Managed.initSet(testing.allocator, -0x7777777799999999ffffeeeeffffeeeeffffeeeef);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0x7777777799999999ffffeeeeffffeeeeffffeeeee);
|
|
defer b.deinit();
|
|
|
|
try testing.expect(a.orderAbs(b) == .gt);
|
|
try testing.expect(a.order(b) == .lt);
|
|
}
|
|
|
|
test "big.int equality" {
|
|
var a = try Managed.initSet(testing.allocator, 0xffffffff1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -0xffffffff1);
|
|
defer b.deinit();
|
|
|
|
try testing.expect(a.eqAbs(b));
|
|
try testing.expect(!a.eq(b));
|
|
}
|
|
|
|
test "big.int abs" {
|
|
var a = try Managed.initSet(testing.allocator, -5);
|
|
defer a.deinit();
|
|
|
|
a.abs();
|
|
try testing.expect((try a.to(u32)) == 5);
|
|
|
|
a.abs();
|
|
try testing.expect((try a.to(u32)) == 5);
|
|
}
|
|
|
|
test "big.int negate" {
|
|
var a = try Managed.initSet(testing.allocator, 5);
|
|
defer a.deinit();
|
|
|
|
a.negate();
|
|
try testing.expect((try a.to(i32)) == -5);
|
|
|
|
a.negate();
|
|
try testing.expect((try a.to(i32)) == 5);
|
|
}
|
|
|
|
test "big.int add single-single" {
|
|
var a = try Managed.initSet(testing.allocator, 50);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 5);
|
|
defer b.deinit();
|
|
|
|
var c = try Managed.init(testing.allocator);
|
|
defer c.deinit();
|
|
try c.add(a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try c.to(u32)) == 55);
|
|
}
|
|
|
|
test "big.int add multi-single" {
|
|
var a = try Managed.initSet(testing.allocator, maxInt(Limb) + 1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 1);
|
|
defer b.deinit();
|
|
|
|
var c = try Managed.init(testing.allocator);
|
|
defer c.deinit();
|
|
|
|
try c.add(a.toConst(), b.toConst());
|
|
try testing.expect((try c.to(DoubleLimb)) == maxInt(Limb) + 2);
|
|
|
|
try c.add(b.toConst(), a.toConst());
|
|
try testing.expect((try c.to(DoubleLimb)) == maxInt(Limb) + 2);
|
|
}
|
|
|
|
test "big.int add multi-multi" {
|
|
const op1 = 0xefefefef7f7f7f7f;
|
|
const op2 = 0xfefefefe9f9f9f9f;
|
|
var a = try Managed.initSet(testing.allocator, op1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, op2);
|
|
defer b.deinit();
|
|
|
|
var c = try Managed.init(testing.allocator);
|
|
defer c.deinit();
|
|
try c.add(a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try c.to(u128)) == op1 + op2);
|
|
}
|
|
|
|
test "big.int add zero-zero" {
|
|
var a = try Managed.initSet(testing.allocator, 0);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0);
|
|
defer b.deinit();
|
|
|
|
var c = try Managed.init(testing.allocator);
|
|
defer c.deinit();
|
|
try c.add(a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try c.to(u32)) == 0);
|
|
}
|
|
|
|
test "big.int add alias multi-limb nonzero-zero" {
|
|
const op1 = 0xffffffff777777771;
|
|
var a = try Managed.initSet(testing.allocator, op1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0);
|
|
defer b.deinit();
|
|
|
|
try a.add(a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try a.to(u128)) == op1);
|
|
}
|
|
|
|
test "big.int add sign" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
|
|
var one = try Managed.initSet(testing.allocator, 1);
|
|
defer one.deinit();
|
|
var two = try Managed.initSet(testing.allocator, 2);
|
|
defer two.deinit();
|
|
var neg_one = try Managed.initSet(testing.allocator, -1);
|
|
defer neg_one.deinit();
|
|
var neg_two = try Managed.initSet(testing.allocator, -2);
|
|
defer neg_two.deinit();
|
|
|
|
try a.add(one.toConst(), two.toConst());
|
|
try testing.expect((try a.to(i32)) == 3);
|
|
|
|
try a.add(neg_one.toConst(), two.toConst());
|
|
try testing.expect((try a.to(i32)) == 1);
|
|
|
|
try a.add(one.toConst(), neg_two.toConst());
|
|
try testing.expect((try a.to(i32)) == -1);
|
|
|
|
try a.add(neg_one.toConst(), neg_two.toConst());
|
|
try testing.expect((try a.to(i32)) == -3);
|
|
}
|
|
|
|
test "big.int add scalar" {
|
|
var a = try Managed.initSet(testing.allocator, 50);
|
|
defer a.deinit();
|
|
|
|
var b = try Managed.init(testing.allocator);
|
|
defer b.deinit();
|
|
try b.addScalar(a.toConst(), 5);
|
|
|
|
try testing.expect((try b.to(u32)) == 55);
|
|
}
|
|
|
|
test "big.int sub single-single" {
|
|
var a = try Managed.initSet(testing.allocator, 50);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 5);
|
|
defer b.deinit();
|
|
|
|
var c = try Managed.init(testing.allocator);
|
|
defer c.deinit();
|
|
try c.sub(a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try c.to(u32)) == 45);
|
|
}
|
|
|
|
test "big.int sub multi-single" {
|
|
var a = try Managed.initSet(testing.allocator, maxInt(Limb) + 1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 1);
|
|
defer b.deinit();
|
|
|
|
var c = try Managed.init(testing.allocator);
|
|
defer c.deinit();
|
|
try c.sub(a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try c.to(Limb)) == maxInt(Limb));
|
|
}
|
|
|
|
test "big.int sub multi-multi" {
|
|
const op1 = 0xefefefefefefefefefefefef;
|
|
const op2 = 0xabababababababababababab;
|
|
|
|
var a = try Managed.initSet(testing.allocator, op1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, op2);
|
|
defer b.deinit();
|
|
|
|
var c = try Managed.init(testing.allocator);
|
|
defer c.deinit();
|
|
try c.sub(a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try c.to(u128)) == op1 - op2);
|
|
}
|
|
|
|
test "big.int sub equal" {
|
|
var a = try Managed.initSet(testing.allocator, 0x11efefefefefefefefefefefef);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0x11efefefefefefefefefefefef);
|
|
defer b.deinit();
|
|
|
|
var c = try Managed.init(testing.allocator);
|
|
defer c.deinit();
|
|
try c.sub(a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try c.to(u32)) == 0);
|
|
}
|
|
|
|
test "big.int sub sign" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
|
|
var one = try Managed.initSet(testing.allocator, 1);
|
|
defer one.deinit();
|
|
var two = try Managed.initSet(testing.allocator, 2);
|
|
defer two.deinit();
|
|
var neg_one = try Managed.initSet(testing.allocator, -1);
|
|
defer neg_one.deinit();
|
|
var neg_two = try Managed.initSet(testing.allocator, -2);
|
|
defer neg_two.deinit();
|
|
|
|
try a.sub(one.toConst(), two.toConst());
|
|
try testing.expect((try a.to(i32)) == -1);
|
|
|
|
try a.sub(neg_one.toConst(), two.toConst());
|
|
try testing.expect((try a.to(i32)) == -3);
|
|
|
|
try a.sub(one.toConst(), neg_two.toConst());
|
|
try testing.expect((try a.to(i32)) == 3);
|
|
|
|
try a.sub(neg_one.toConst(), neg_two.toConst());
|
|
try testing.expect((try a.to(i32)) == 1);
|
|
|
|
try a.sub(neg_two.toConst(), neg_one.toConst());
|
|
try testing.expect((try a.to(i32)) == -1);
|
|
}
|
|
|
|
test "big.int mul single-single" {
|
|
var a = try Managed.initSet(testing.allocator, 50);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 5);
|
|
defer b.deinit();
|
|
|
|
var c = try Managed.init(testing.allocator);
|
|
defer c.deinit();
|
|
try c.mul(a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try c.to(u64)) == 250);
|
|
}
|
|
|
|
test "big.int mul multi-single" {
|
|
var a = try Managed.initSet(testing.allocator, maxInt(Limb));
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 2);
|
|
defer b.deinit();
|
|
|
|
var c = try Managed.init(testing.allocator);
|
|
defer c.deinit();
|
|
try c.mul(a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try c.to(DoubleLimb)) == 2 * maxInt(Limb));
|
|
}
|
|
|
|
test "big.int mul multi-multi" {
|
|
const op1 = 0x998888efefefefefefefef;
|
|
const op2 = 0x333000abababababababab;
|
|
var a = try Managed.initSet(testing.allocator, op1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, op2);
|
|
defer b.deinit();
|
|
|
|
var c = try Managed.init(testing.allocator);
|
|
defer c.deinit();
|
|
try c.mul(a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try c.to(u256)) == op1 * op2);
|
|
}
|
|
|
|
test "big.int mul alias r with a" {
|
|
var a = try Managed.initSet(testing.allocator, maxInt(Limb));
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 2);
|
|
defer b.deinit();
|
|
|
|
try a.mul(a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try a.to(DoubleLimb)) == 2 * maxInt(Limb));
|
|
}
|
|
|
|
test "big.int mul alias r with b" {
|
|
var a = try Managed.initSet(testing.allocator, maxInt(Limb));
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 2);
|
|
defer b.deinit();
|
|
|
|
try a.mul(b.toConst(), a.toConst());
|
|
|
|
try testing.expect((try a.to(DoubleLimb)) == 2 * maxInt(Limb));
|
|
}
|
|
|
|
test "big.int mul alias r with a and b" {
|
|
var a = try Managed.initSet(testing.allocator, maxInt(Limb));
|
|
defer a.deinit();
|
|
|
|
try a.mul(a.toConst(), a.toConst());
|
|
|
|
try testing.expect((try a.to(DoubleLimb)) == maxInt(Limb) * maxInt(Limb));
|
|
}
|
|
|
|
test "big.int mul a*0" {
|
|
var a = try Managed.initSet(testing.allocator, 0xefefefefefefefef);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0);
|
|
defer b.deinit();
|
|
|
|
var c = try Managed.init(testing.allocator);
|
|
defer c.deinit();
|
|
try c.mul(a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try c.to(u32)) == 0);
|
|
}
|
|
|
|
test "big.int mul 0*0" {
|
|
var a = try Managed.initSet(testing.allocator, 0);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0);
|
|
defer b.deinit();
|
|
|
|
var c = try Managed.init(testing.allocator);
|
|
defer c.deinit();
|
|
try c.mul(a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try c.to(u32)) == 0);
|
|
}
|
|
|
|
test "big.int mul large" {
|
|
var a = try Managed.initCapacity(testing.allocator, 50);
|
|
defer a.deinit();
|
|
var b = try Managed.initCapacity(testing.allocator, 100);
|
|
defer b.deinit();
|
|
var c = try Managed.initCapacity(testing.allocator, 100);
|
|
defer c.deinit();
|
|
|
|
// Generate a number that's large enough to cross the thresholds for the use
|
|
// of subquadratic algorithms
|
|
for (a.limbs) |*p| {
|
|
p.* = std.math.maxInt(Limb);
|
|
}
|
|
a.setMetadata(true, 50);
|
|
|
|
try b.mul(a.toConst(), a.toConst());
|
|
try c.sqr(a.toConst());
|
|
|
|
try testing.expect(b.eq(c));
|
|
}
|
|
|
|
test "big.int div single-single no rem" {
|
|
var a = try Managed.initSet(testing.allocator, 50);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 5);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try q.to(u32)) == 10);
|
|
try testing.expect((try r.to(u32)) == 0);
|
|
}
|
|
|
|
test "big.int div single-single with rem" {
|
|
var a = try Managed.initSet(testing.allocator, 49);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 5);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try q.to(u32)) == 9);
|
|
try testing.expect((try r.to(u32)) == 4);
|
|
}
|
|
|
|
test "big.int div multi-single no rem" {
|
|
const op1 = 0xffffeeeeddddcccc;
|
|
const op2 = 34;
|
|
|
|
var a = try Managed.initSet(testing.allocator, op1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, op2);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try q.to(u64)) == op1 / op2);
|
|
try testing.expect((try r.to(u64)) == 0);
|
|
}
|
|
|
|
test "big.int div multi-single with rem" {
|
|
const op1 = 0xffffeeeeddddcccf;
|
|
const op2 = 34;
|
|
|
|
var a = try Managed.initSet(testing.allocator, op1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, op2);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try q.to(u64)) == op1 / op2);
|
|
try testing.expect((try r.to(u64)) == 3);
|
|
}
|
|
|
|
test "big.int div multi>2-single" {
|
|
const op1 = 0xfefefefefefefefefefefefefefefefe;
|
|
const op2 = 0xefab8;
|
|
|
|
var a = try Managed.initSet(testing.allocator, op1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, op2);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try q.to(u128)) == op1 / op2);
|
|
try testing.expect((try r.to(u32)) == 0x3e4e);
|
|
}
|
|
|
|
test "big.int div single-single q < r" {
|
|
var a = try Managed.initSet(testing.allocator, 0x0078f432);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0x01000000);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try q.to(u64)) == 0);
|
|
try testing.expect((try r.to(u64)) == 0x0078f432);
|
|
}
|
|
|
|
test "big.int div single-single q == r" {
|
|
var a = try Managed.initSet(testing.allocator, 10);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 10);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try q.to(u64)) == 1);
|
|
try testing.expect((try r.to(u64)) == 0);
|
|
}
|
|
|
|
test "big.int div q=0 alias" {
|
|
var a = try Managed.initSet(testing.allocator, 3);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 10);
|
|
defer b.deinit();
|
|
|
|
try Managed.divTrunc(&a, &b, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try a.to(u64)) == 0);
|
|
try testing.expect((try b.to(u64)) == 3);
|
|
}
|
|
|
|
test "big.int div multi-multi q < r" {
|
|
const op1 = 0x1ffffffff0078f432;
|
|
const op2 = 0x1ffffffff01000000;
|
|
var a = try Managed.initSet(testing.allocator, op1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, op2);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try q.to(u128)) == 0);
|
|
try testing.expect((try r.to(u128)) == op1);
|
|
}
|
|
|
|
test "big.int div trunc single-single +/+" {
|
|
const u: i32 = 5;
|
|
const v: i32 = 3;
|
|
|
|
var a = try Managed.initSet(testing.allocator, u);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, v);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
// n = q * d + r
|
|
// 5 = 1 * 3 + 2
|
|
const eq = @divTrunc(u, v);
|
|
const er = @mod(u, v);
|
|
|
|
try testing.expect((try q.to(i32)) == eq);
|
|
try testing.expect((try r.to(i32)) == er);
|
|
}
|
|
|
|
test "big.int div trunc single-single -/+" {
|
|
const u: i32 = -5;
|
|
const v: i32 = 3;
|
|
|
|
var a = try Managed.initSet(testing.allocator, u);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, v);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
// n = q * d + r
|
|
// -5 = 1 * -3 - 2
|
|
const eq = -1;
|
|
const er = -2;
|
|
|
|
try testing.expect((try q.to(i32)) == eq);
|
|
try testing.expect((try r.to(i32)) == er);
|
|
}
|
|
|
|
test "big.int div trunc single-single +/-" {
|
|
const u: i32 = 5;
|
|
const v: i32 = -3;
|
|
|
|
var a = try Managed.initSet(testing.allocator, u);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, v);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
// n = q * d + r
|
|
// 5 = -1 * -3 + 2
|
|
const eq = -1;
|
|
const er = 2;
|
|
|
|
try testing.expect((try q.to(i32)) == eq);
|
|
try testing.expect((try r.to(i32)) == er);
|
|
}
|
|
|
|
test "big.int div trunc single-single -/-" {
|
|
const u: i32 = -5;
|
|
const v: i32 = -3;
|
|
|
|
var a = try Managed.initSet(testing.allocator, u);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, v);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
// n = q * d + r
|
|
// -5 = 1 * -3 - 2
|
|
const eq = 1;
|
|
const er = -2;
|
|
|
|
try testing.expect((try q.to(i32)) == eq);
|
|
try testing.expect((try r.to(i32)) == er);
|
|
}
|
|
|
|
test "big.int div floor single-single +/+" {
|
|
const u: i32 = 5;
|
|
const v: i32 = 3;
|
|
|
|
var a = try Managed.initSet(testing.allocator, u);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, v);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divFloor(&q, &r, a.toConst(), b.toConst());
|
|
|
|
// n = q * d + r
|
|
// 5 = 1 * 3 + 2
|
|
const eq = 1;
|
|
const er = 2;
|
|
|
|
try testing.expect((try q.to(i32)) == eq);
|
|
try testing.expect((try r.to(i32)) == er);
|
|
}
|
|
|
|
test "big.int div floor single-single -/+" {
|
|
const u: i32 = -5;
|
|
const v: i32 = 3;
|
|
|
|
var a = try Managed.initSet(testing.allocator, u);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, v);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divFloor(&q, &r, a.toConst(), b.toConst());
|
|
|
|
// n = q * d + r
|
|
// -5 = -2 * 3 + 1
|
|
const eq = -2;
|
|
const er = 1;
|
|
|
|
try testing.expect((try q.to(i32)) == eq);
|
|
try testing.expect((try r.to(i32)) == er);
|
|
}
|
|
|
|
test "big.int div floor single-single +/-" {
|
|
const u: i32 = 5;
|
|
const v: i32 = -3;
|
|
|
|
var a = try Managed.initSet(testing.allocator, u);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, v);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divFloor(&q, &r, a.toConst(), b.toConst());
|
|
|
|
// n = q * d + r
|
|
// 5 = -2 * -3 - 1
|
|
const eq = -2;
|
|
const er = -1;
|
|
|
|
try testing.expect((try q.to(i32)) == eq);
|
|
try testing.expect((try r.to(i32)) == er);
|
|
}
|
|
|
|
test "big.int div floor single-single -/-" {
|
|
const u: i32 = -5;
|
|
const v: i32 = -3;
|
|
|
|
var a = try Managed.initSet(testing.allocator, u);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, v);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divFloor(&q, &r, a.toConst(), b.toConst());
|
|
|
|
// n = q * d + r
|
|
// -5 = 2 * -3 + 1
|
|
const eq = 1;
|
|
const er = -2;
|
|
|
|
try testing.expect((try q.to(i32)) == eq);
|
|
try testing.expect((try r.to(i32)) == er);
|
|
}
|
|
|
|
test "big.int div multi-multi with rem" {
|
|
var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeeddddccccbbbbaaaa9999);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);
|
|
try testing.expect((try r.to(u128)) == 0x28de0acacd806823638);
|
|
}
|
|
|
|
test "big.int div multi-multi no rem" {
|
|
var a = try Managed.initSet(testing.allocator, 0x8888999911110000ffffeeeedb4fec200ee3a4286361);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0x99990000111122223333);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try q.to(u128)) == 0xe38f38e39161aaabd03f0f1b);
|
|
try testing.expect((try r.to(u128)) == 0);
|
|
}
|
|
|
|
test "big.int div multi-multi (2 branch)" {
|
|
var a = try Managed.initSet(testing.allocator, 0x866666665555555588888887777777761111111111111111);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0x86666666555555554444444433333333);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try q.to(u128)) == 0x10000000000000000);
|
|
try testing.expect((try r.to(u128)) == 0x44444443444444431111111111111111);
|
|
}
|
|
|
|
test "big.int div multi-multi (3.1/3.3 branch)" {
|
|
var a = try Managed.initSet(testing.allocator, 0x11111111111111111111111111111111111111111111111111111111111111);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0x1111111111111111111111111111111111111111171);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try q.to(u128)) == 0xfffffffffffffffffff);
|
|
try testing.expect((try r.to(u256)) == 0x1111111111111111111110b12222222222222222282);
|
|
}
|
|
|
|
test "big.int div multi-single zero-limb trailing" {
|
|
var a = try Managed.initSet(testing.allocator, 0x60000000000000000000000000000000000000000000000000000000000000000);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0x10000000000000000);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
var expected = try Managed.initSet(testing.allocator, 0x6000000000000000000000000000000000000000000000000);
|
|
defer expected.deinit();
|
|
try testing.expect(q.eq(expected));
|
|
try testing.expect(r.eqZero());
|
|
}
|
|
|
|
test "big.int div multi-multi zero-limb trailing (with rem)" {
|
|
var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try q.to(u128)) == 0x10000000000000000);
|
|
|
|
const rs = try r.toString(testing.allocator, 16, .lower);
|
|
defer testing.allocator.free(rs);
|
|
try testing.expect(std.mem.eql(u8, rs, "4444444344444443111111111111111100000000000000000000000000000000"));
|
|
}
|
|
|
|
test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count > divisor zero-limb count" {
|
|
var a = try Managed.initSet(testing.allocator, 0x8666666655555555888888877777777611111111111111110000000000000000);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0x8666666655555555444444443333333300000000000000000000000000000000);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
try testing.expect((try q.to(u128)) == 0x1);
|
|
|
|
const rs = try r.toString(testing.allocator, 16, .lower);
|
|
defer testing.allocator.free(rs);
|
|
try testing.expect(std.mem.eql(u8, rs, "444444434444444311111111111111110000000000000000"));
|
|
}
|
|
|
|
test "big.int div multi-multi zero-limb trailing (with rem) and dividend zero-limb count < divisor zero-limb count" {
|
|
var a = try Managed.initSet(testing.allocator, 0x86666666555555558888888777777776111111111111111100000000000000000000000000000000);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0x866666665555555544444444333333330000000000000000);
|
|
defer b.deinit();
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
const qs = try q.toString(testing.allocator, 16, .lower);
|
|
defer testing.allocator.free(qs);
|
|
try testing.expect(std.mem.eql(u8, qs, "10000000000000000820820803105186f"));
|
|
|
|
const rs = try r.toString(testing.allocator, 16, .lower);
|
|
defer testing.allocator.free(rs);
|
|
try testing.expect(std.mem.eql(u8, rs, "4e11f2baa5896a321d463b543d0104e30000000000000000"));
|
|
}
|
|
|
|
test "big.int div multi-multi fuzz case #1" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
var b = try Managed.init(testing.allocator);
|
|
defer b.deinit();
|
|
|
|
try a.setString(16, "ffffffffffffffffffffffffffffc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
|
|
try b.setString(16, "3ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000000000000000000001ffffffffffffffffffffffffffffffffffffffffffffffffffc000000000000000000000000000000007fffffffffff");
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
const qs = try q.toString(testing.allocator, 16, .lower);
|
|
defer testing.allocator.free(qs);
|
|
try testing.expect(std.mem.eql(u8, qs, "3ffffffffffffffffffffffffffff0000000000000000000000000000000000001ffffffffffffffffffffffffffff7fffffffe000000000000000000000000000180000000000000000000003fffffbfffffffdfffffffffffffeffff800000100101000000100000000020003fffffdfbfffffe3ffffffffffffeffff7fffc00800a100000017ffe000002000400007efbfff7fe9f00000037ffff3fff7fffa004006100000009ffe00000190038200bf7d2ff7fefe80400060000f7d7f8fbf9401fe38e0403ffc0bdffffa51102c300d7be5ef9df4e5060007b0127ad3fa69f97d0f820b6605ff617ddf7f32ad7a05c0d03f2e7bc78a6000e087a8bbcdc59e07a5a079128a7861f553ddebed7e8e56701756f9ead39b48cd1b0831889ea6ec1fddf643d0565b075ff07e6caea4e2854ec9227fd635ed60a2f5eef2893052ffd54718fa08604acbf6a15e78a467c4a3c53c0278af06c4416573f925491b195e8fd79302cb1aaf7caf4ecfc9aec1254cc969786363ac729f914c6ddcc26738d6b0facd54eba026580aba2eb6482a088b0d224a8852420b91ec1"));
|
|
|
|
const rs = try r.toString(testing.allocator, 16, .lower);
|
|
defer testing.allocator.free(rs);
|
|
try testing.expect(std.mem.eql(u8, rs, "310d1d4c414426b4836c2635bad1df3a424e50cbdd167ffccb4dfff57d36b4aae0d6ca0910698220171a0f3373c1060a046c2812f0027e321f72979daa5e7973214170d49e885de0c0ecc167837d44502430674a82522e5df6a0759548052420b91ec1"));
|
|
}
|
|
|
|
test "big.int div multi-multi fuzz case #2" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
var b = try Managed.init(testing.allocator);
|
|
defer b.deinit();
|
|
|
|
try a.setString(16, "3ffffffffe00000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000000000000000001fffffffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffc000000000000000000000000000000000000000000000000000000000000000");
|
|
try b.setString(16, "ffc0000000000000000000000000000000000000000000000000");
|
|
|
|
var q = try Managed.init(testing.allocator);
|
|
defer q.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
try Managed.divTrunc(&q, &r, a.toConst(), b.toConst());
|
|
|
|
const qs = try q.toString(testing.allocator, 16, .lower);
|
|
defer testing.allocator.free(qs);
|
|
try testing.expect(std.mem.eql(u8, qs, "40100400fe3f8fe3f8fe3f8fe3f8fe3f8fe4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f93e4f91e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4992649926499264991e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4791e4792e4b92e4b92e4b92e4b92a4a92a4a92a4"));
|
|
|
|
const rs = try r.toString(testing.allocator, 16, .lower);
|
|
defer testing.allocator.free(rs);
|
|
try testing.expect(std.mem.eql(u8, rs, "a900000000000000000000000000000000000000000000000000"));
|
|
}
|
|
|
|
test "big.int shift-right single" {
|
|
var a = try Managed.initSet(testing.allocator, 0xffff0000);
|
|
defer a.deinit();
|
|
try a.shiftRight(a, 16);
|
|
|
|
try testing.expect((try a.to(u32)) == 0xffff);
|
|
}
|
|
|
|
test "big.int shift-right multi" {
|
|
var a = try Managed.initSet(testing.allocator, 0xffff0000eeee1111dddd2222cccc3333);
|
|
defer a.deinit();
|
|
try a.shiftRight(a, 67);
|
|
|
|
try testing.expect((try a.to(u64)) == 0x1fffe0001dddc222);
|
|
|
|
try a.set(0xffff0000eeee1111dddd2222cccc3333);
|
|
try a.shiftRight(a, 63);
|
|
try a.shiftRight(a, 63);
|
|
try a.shiftRight(a, 2);
|
|
try testing.expect(a.eqZero());
|
|
}
|
|
|
|
test "big.int shift-left single" {
|
|
var a = try Managed.initSet(testing.allocator, 0xffff);
|
|
defer a.deinit();
|
|
try a.shiftLeft(a, 16);
|
|
|
|
try testing.expect((try a.to(u64)) == 0xffff0000);
|
|
}
|
|
|
|
test "big.int shift-left multi" {
|
|
var a = try Managed.initSet(testing.allocator, 0x1fffe0001dddc222);
|
|
defer a.deinit();
|
|
try a.shiftLeft(a, 67);
|
|
|
|
try testing.expect((try a.to(u128)) == 0xffff0000eeee11100000000000000000);
|
|
}
|
|
|
|
test "big.int shift-right negative" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
|
|
var arg = try Managed.initSet(testing.allocator, -20);
|
|
defer arg.deinit();
|
|
try a.shiftRight(arg, 2);
|
|
try testing.expect((try a.to(i32)) == -20 >> 2);
|
|
|
|
var arg2 = try Managed.initSet(testing.allocator, -5);
|
|
defer arg2.deinit();
|
|
try a.shiftRight(arg2, 10);
|
|
try testing.expect((try a.to(i32)) == -5 >> 10);
|
|
}
|
|
|
|
test "big.int shift-left negative" {
|
|
var a = try Managed.init(testing.allocator);
|
|
defer a.deinit();
|
|
|
|
var arg = try Managed.initSet(testing.allocator, -10);
|
|
defer arg.deinit();
|
|
try a.shiftRight(arg, 1232);
|
|
try testing.expect((try a.to(i32)) == -10 >> 1232);
|
|
}
|
|
|
|
test "big.int bitwise and simple" {
|
|
var a = try Managed.initSet(testing.allocator, 0xffffffff11111111);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0xeeeeeeee22222222);
|
|
defer b.deinit();
|
|
|
|
try a.bitAnd(a, b);
|
|
|
|
try testing.expect((try a.to(u64)) == 0xeeeeeeee00000000);
|
|
}
|
|
|
|
test "big.int bitwise and multi-limb" {
|
|
var a = try Managed.initSet(testing.allocator, maxInt(Limb) + 1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, maxInt(Limb));
|
|
defer b.deinit();
|
|
|
|
try a.bitAnd(a, b);
|
|
|
|
try testing.expect((try a.to(u128)) == 0);
|
|
}
|
|
|
|
test "big.int bitwise and negative-positive simple" {
|
|
var a = try Managed.initSet(testing.allocator, -0xffffffff11111111);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0xeeeeeeee22222222);
|
|
defer b.deinit();
|
|
|
|
try a.bitAnd(a, b);
|
|
|
|
try testing.expect((try a.to(u64)) == 0x22222222);
|
|
}
|
|
|
|
test "big.int bitwise and negative-positive multi-limb" {
|
|
var a = try Managed.initSet(testing.allocator, -maxInt(Limb) - 1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, maxInt(Limb));
|
|
defer b.deinit();
|
|
|
|
try a.bitAnd(a, b);
|
|
|
|
try testing.expect(a.eqZero());
|
|
}
|
|
|
|
test "big.int bitwise and positive-negative simple" {
|
|
var a = try Managed.initSet(testing.allocator, 0xffffffff11111111);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -0xeeeeeeee22222222);
|
|
defer b.deinit();
|
|
|
|
try a.bitAnd(a, b);
|
|
|
|
try testing.expect((try a.to(u64)) == 0x1111111111111110);
|
|
}
|
|
|
|
test "big.int bitwise and positive-negative multi-limb" {
|
|
var a = try Managed.initSet(testing.allocator, maxInt(Limb));
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -maxInt(Limb) - 1);
|
|
defer b.deinit();
|
|
|
|
try a.bitAnd(a, b);
|
|
|
|
try testing.expect(a.eqZero());
|
|
}
|
|
|
|
test "big.int bitwise and negative-negative simple" {
|
|
var a = try Managed.initSet(testing.allocator, -0xffffffff11111111);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -0xeeeeeeee22222222);
|
|
defer b.deinit();
|
|
|
|
try a.bitAnd(a, b);
|
|
|
|
try testing.expect((try a.to(i128)) == -0xffffffff33333332);
|
|
}
|
|
|
|
test "big.int bitwise and negative-negative multi-limb" {
|
|
var a = try Managed.initSet(testing.allocator, -maxInt(Limb) - 1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -maxInt(Limb) - 2);
|
|
defer b.deinit();
|
|
|
|
try a.bitAnd(a, b);
|
|
|
|
try testing.expect((try a.to(i128)) == -maxInt(Limb) * 2 - 2);
|
|
}
|
|
|
|
test "big.int bitwise and negative overflow" {
|
|
var a = try Managed.initSet(testing.allocator, -maxInt(Limb));
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -2);
|
|
defer b.deinit();
|
|
|
|
try a.bitAnd(a, b);
|
|
|
|
try testing.expect((try a.to(SignedDoubleLimb)) == -maxInt(Limb) - 1);
|
|
}
|
|
|
|
test "big.int bitwise xor simple" {
|
|
var a = try Managed.initSet(testing.allocator, 0xffffffff11111111);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0xeeeeeeee22222222);
|
|
defer b.deinit();
|
|
|
|
try a.bitXor(a, b);
|
|
|
|
try testing.expect((try a.to(u64)) == 0x1111111133333333);
|
|
}
|
|
|
|
test "big.int bitwise xor multi-limb" {
|
|
var a = try Managed.initSet(testing.allocator, maxInt(Limb) + 1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, maxInt(Limb));
|
|
defer b.deinit();
|
|
|
|
try a.bitXor(a, b);
|
|
|
|
try testing.expect((try a.to(DoubleLimb)) == (maxInt(Limb) + 1) ^ maxInt(Limb));
|
|
}
|
|
|
|
test "big.int bitwise xor single negative simple" {
|
|
var a = try Managed.initSet(testing.allocator, 0x6b03e381328a3154);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -0x45fd3acef9191fad);
|
|
defer b.deinit();
|
|
|
|
try a.bitXor(a, b);
|
|
|
|
try testing.expect((try a.to(i64)) == -0x2efed94fcb932ef9);
|
|
}
|
|
|
|
test "big.int bitwise xor single negative zero" {
|
|
var a = try Managed.initSet(testing.allocator, 0);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -0);
|
|
defer b.deinit();
|
|
|
|
try a.bitXor(a, b);
|
|
|
|
try testing.expect(a.eqZero());
|
|
}
|
|
|
|
test "big.int bitwise xor single negative multi-limb" {
|
|
var a = try Managed.initSet(testing.allocator, -0x9849c6e7a10d66d0e4260d4846254c32);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0xf2194e7d1c855272a997fcde16f6d5a8);
|
|
defer b.deinit();
|
|
|
|
try a.bitXor(a, b);
|
|
|
|
try testing.expect((try a.to(i128)) == -0x6a50889abd8834a24db1f19650d3999a);
|
|
}
|
|
|
|
test "big.int bitwise xor single negative overflow" {
|
|
var a = try Managed.initSet(testing.allocator, maxInt(Limb));
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -1);
|
|
defer b.deinit();
|
|
|
|
try a.bitXor(a, b);
|
|
|
|
try testing.expect((try a.to(SignedDoubleLimb)) == -(maxInt(Limb) + 1));
|
|
}
|
|
|
|
test "big.int bitwise xor double negative simple" {
|
|
var a = try Managed.initSet(testing.allocator, -0x8e48bd5f755ef1f3);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -0x4dd4fa576f3046ac);
|
|
defer b.deinit();
|
|
|
|
try a.bitXor(a, b);
|
|
|
|
try testing.expect((try a.to(u64)) == 0xc39c47081a6eb759);
|
|
}
|
|
|
|
test "big.int bitwise xor double negative multi-limb" {
|
|
var a = try Managed.initSet(testing.allocator, -0x684e5da8f500ec8ca7204c33ccc51c9c);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -0xcb07736a7b62289c78d967c3985eebeb);
|
|
defer b.deinit();
|
|
|
|
try a.bitXor(a, b);
|
|
|
|
try testing.expect((try a.to(u128)) == 0xa3492ec28e62c410dff92bf0549bf771);
|
|
}
|
|
|
|
test "big.int bitwise or simple" {
|
|
var a = try Managed.initSet(testing.allocator, 0xffffffff11111111);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0xeeeeeeee22222222);
|
|
defer b.deinit();
|
|
|
|
try a.bitOr(a, b);
|
|
|
|
try testing.expect((try a.to(u64)) == 0xffffffff33333333);
|
|
}
|
|
|
|
test "big.int bitwise or multi-limb" {
|
|
var a = try Managed.initSet(testing.allocator, maxInt(Limb) + 1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, maxInt(Limb));
|
|
defer b.deinit();
|
|
|
|
try a.bitOr(a, b);
|
|
|
|
// TODO: big.int.cpp or is wrong on multi-limb.
|
|
try testing.expect((try a.to(DoubleLimb)) == (maxInt(Limb) + 1) + maxInt(Limb));
|
|
}
|
|
|
|
test "big.int bitwise or negative-positive simple" {
|
|
var a = try Managed.initSet(testing.allocator, -0xffffffff11111111);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0xeeeeeeee22222222);
|
|
defer b.deinit();
|
|
|
|
try a.bitOr(a, b);
|
|
|
|
try testing.expect((try a.to(i64)) == -0x1111111111111111);
|
|
}
|
|
|
|
test "big.int bitwise or negative-positive multi-limb" {
|
|
var a = try Managed.initSet(testing.allocator, -maxInt(Limb) - 1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 1);
|
|
defer b.deinit();
|
|
|
|
try a.bitOr(a, b);
|
|
|
|
try testing.expect((try a.to(SignedDoubleLimb)) == -maxInt(Limb));
|
|
}
|
|
|
|
test "big.int bitwise or positive-negative simple" {
|
|
var a = try Managed.initSet(testing.allocator, 0xffffffff11111111);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -0xeeeeeeee22222222);
|
|
defer b.deinit();
|
|
|
|
try a.bitOr(a, b);
|
|
|
|
try testing.expect((try a.to(i64)) == -0x22222221);
|
|
}
|
|
|
|
test "big.int bitwise or positive-negative multi-limb" {
|
|
var a = try Managed.initSet(testing.allocator, maxInt(Limb) + 1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -1);
|
|
defer b.deinit();
|
|
|
|
try a.bitOr(a, b);
|
|
|
|
try testing.expect((try a.to(SignedDoubleLimb)) == -1);
|
|
}
|
|
|
|
test "big.int bitwise or negative-negative simple" {
|
|
var a = try Managed.initSet(testing.allocator, -0xffffffff11111111);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -0xeeeeeeee22222222);
|
|
defer b.deinit();
|
|
|
|
try a.bitOr(a, b);
|
|
|
|
try testing.expect((try a.to(i128)) == -0xeeeeeeee00000001);
|
|
}
|
|
|
|
test "big.int bitwise or negative-negative multi-limb" {
|
|
var a = try Managed.initSet(testing.allocator, -maxInt(Limb) - 1);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, -maxInt(Limb));
|
|
defer b.deinit();
|
|
|
|
try a.bitOr(a, b);
|
|
|
|
try testing.expect((try a.to(SignedDoubleLimb)) == -maxInt(Limb));
|
|
}
|
|
|
|
test "big.int var args" {
|
|
var a = try Managed.initSet(testing.allocator, 5);
|
|
defer a.deinit();
|
|
|
|
var b = try Managed.initSet(testing.allocator, 6);
|
|
defer b.deinit();
|
|
try a.add(a.toConst(), b.toConst());
|
|
try testing.expect((try a.to(u64)) == 11);
|
|
|
|
var c = try Managed.initSet(testing.allocator, 11);
|
|
defer c.deinit();
|
|
try testing.expect(a.order(c) == .eq);
|
|
|
|
var d = try Managed.initSet(testing.allocator, 14);
|
|
defer d.deinit();
|
|
try testing.expect(a.order(d) != .gt);
|
|
}
|
|
|
|
test "big.int gcd non-one small" {
|
|
var a = try Managed.initSet(testing.allocator, 17);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 97);
|
|
defer b.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
|
|
try r.gcd(a, b);
|
|
|
|
try testing.expect((try r.to(u32)) == 1);
|
|
}
|
|
|
|
test "big.int gcd non-one small" {
|
|
var a = try Managed.initSet(testing.allocator, 4864);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 3458);
|
|
defer b.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
|
|
try r.gcd(a, b);
|
|
|
|
try testing.expect((try r.to(u32)) == 38);
|
|
}
|
|
|
|
test "big.int gcd non-one large" {
|
|
var a = try Managed.initSet(testing.allocator, 0xffffffffffffffff);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0xffffffffffffffff7777);
|
|
defer b.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
|
|
try r.gcd(a, b);
|
|
|
|
try testing.expect((try r.to(u32)) == 4369);
|
|
}
|
|
|
|
test "big.int gcd large multi-limb result" {
|
|
var a = try Managed.initSet(testing.allocator, 0x12345678123456781234567812345678123456781234567812345678);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 0x12345671234567123456712345671234567123456712345671234567);
|
|
defer b.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
|
|
try r.gcd(a, b);
|
|
|
|
const answer = (try r.to(u256));
|
|
try testing.expect(answer == 0xf000000ff00000fff0000ffff000fffff00ffffff1);
|
|
}
|
|
|
|
test "big.int gcd one large" {
|
|
var a = try Managed.initSet(testing.allocator, 1897056385327307);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 2251799813685248);
|
|
defer b.deinit();
|
|
var r = try Managed.init(testing.allocator);
|
|
defer r.deinit();
|
|
|
|
try r.gcd(a, b);
|
|
|
|
try testing.expect((try r.to(u64)) == 1);
|
|
}
|
|
|
|
test "big.int mutable to managed" {
|
|
const allocator = testing.allocator;
|
|
var limbs_buf = try allocator.alloc(Limb, 8);
|
|
defer allocator.free(limbs_buf);
|
|
|
|
var a = Mutable.init(limbs_buf, 0xdeadbeef);
|
|
var a_managed = a.toManaged(allocator);
|
|
|
|
try testing.expect(a.toConst().eq(a_managed.toConst()));
|
|
}
|
|
|
|
test "big.int const to managed" {
|
|
var a = try Managed.initSet(testing.allocator, 123423453456);
|
|
defer a.deinit();
|
|
|
|
var b = try a.toConst().toManaged(testing.allocator);
|
|
defer b.deinit();
|
|
|
|
try testing.expect(a.toConst().eq(b.toConst()));
|
|
}
|
|
|
|
test "big.int pow" {
|
|
{
|
|
var a = try Managed.initSet(testing.allocator, -3);
|
|
defer a.deinit();
|
|
|
|
try a.pow(a.toConst(), 3);
|
|
try testing.expectEqual(@as(i32, -27), try a.to(i32));
|
|
|
|
try a.pow(a.toConst(), 4);
|
|
try testing.expectEqual(@as(i32, 531441), try a.to(i32));
|
|
}
|
|
{
|
|
var a = try Managed.initSet(testing.allocator, 10);
|
|
defer a.deinit();
|
|
|
|
var y = try Managed.init(testing.allocator);
|
|
defer y.deinit();
|
|
|
|
// y and a are not aliased
|
|
try y.pow(a.toConst(), 123);
|
|
// y and a are aliased
|
|
try a.pow(a.toConst(), 123);
|
|
|
|
try testing.expect(a.eq(y));
|
|
|
|
const ys = try y.toString(testing.allocator, 16, .lower);
|
|
defer testing.allocator.free(ys);
|
|
try testing.expectEqualSlices(
|
|
u8,
|
|
"183425a5f872f126e00a5ad62c839075cd6846c6fb0230887c7ad7a9dc530fcb" ++
|
|
"4933f60e8000000000000000000000000000000",
|
|
ys,
|
|
);
|
|
}
|
|
// Special cases
|
|
{
|
|
var a = try Managed.initSet(testing.allocator, 0);
|
|
defer a.deinit();
|
|
|
|
try a.pow(a.toConst(), 100);
|
|
try testing.expectEqual(@as(i32, 0), try a.to(i32));
|
|
|
|
try a.set(1);
|
|
try a.pow(a.toConst(), 0);
|
|
try testing.expectEqual(@as(i32, 1), try a.to(i32));
|
|
try a.pow(a.toConst(), 100);
|
|
try testing.expectEqual(@as(i32, 1), try a.to(i32));
|
|
try a.set(-1);
|
|
try a.pow(a.toConst(), 15);
|
|
try testing.expectEqual(@as(i32, -1), try a.to(i32));
|
|
try a.pow(a.toConst(), 16);
|
|
try testing.expectEqual(@as(i32, 1), try a.to(i32));
|
|
}
|
|
}
|
|
|
|
test "big.int regression test for 1 limb overflow with alias" {
|
|
// Note these happen to be two consecutive Fibonacci sequence numbers, the
|
|
// first two whose sum exceeds 2**64.
|
|
var a = try Managed.initSet(testing.allocator, 7540113804746346429);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 12200160415121876738);
|
|
defer b.deinit();
|
|
|
|
try a.ensureAddCapacity(a.toConst(), b.toConst());
|
|
try a.add(a.toConst(), b.toConst());
|
|
|
|
try testing.expect(a.toConst().orderAgainstScalar(19740274219868223167) == .eq);
|
|
}
|
|
|
|
test "big.int regression test for realloc with alias" {
|
|
// Note these happen to be two consecutive Fibonacci sequence numbers, the
|
|
// second of which is the first such number to exceed 2**192.
|
|
var a = try Managed.initSet(testing.allocator, 5611500259351924431073312796924978741056961814867751431689);
|
|
defer a.deinit();
|
|
var b = try Managed.initSet(testing.allocator, 9079598147510263717870894449029933369491131786514446266146);
|
|
defer b.deinit();
|
|
|
|
try a.ensureAddCapacity(a.toConst(), b.toConst());
|
|
try a.add(a.toConst(), b.toConst());
|
|
|
|
try testing.expect(a.toConst().orderAgainstScalar(14691098406862188148944207245954912110548093601382197697835) == .eq);
|
|
}
|