pure @safe unittest { import std.bigint; ubyte[] magnitude = [1, 2, 3, 4, 5, 6]; auto b1 = BigInt(false, magnitude); assert(cast(long) b1 == 0x01_02_03_04_05_06L); auto b2 = BigInt(true, magnitude); assert(cast(long) b2 == -0x01_02_03_04_05_06L); } @safe unittest { import std.bigint; ulong data = 1_000_000_000_000; auto bigData = BigInt(data); assert(bigData == BigInt("1_000_000_000_000")); } @safe unittest { import std.bigint; const(BigInt) b1 = BigInt("1_234_567_890"); BigInt b2 = BigInt(b1); assert(b2 == BigInt("1_234_567_890")); } @safe unittest { import std.bigint; auto b = BigInt("123"); b = 456; assert(b == BigInt("456")); } @safe unittest { import std.bigint; auto b1 = BigInt("123"); auto b2 = BigInt("456"); b2 = b1; assert(b2 == BigInt("123")); } @safe unittest { import std.bigint; auto b = BigInt("1_000_000_000"); b += 12345; assert(b == BigInt("1_000_012_345")); b /= 5; assert(b == BigInt("200_002_469")); } @safe unittest { import std.bigint; auto x = BigInt("123"); auto y = BigInt("321"); x += y; assert(x == BigInt("444")); } @safe unittest { import std.bigint; auto x = BigInt("123"); auto y = BigInt("456"); BigInt z = x * y; assert(z == BigInt("56088")); } @safe unittest { import std.bigint; auto x = BigInt("123"); x *= 300; assert(x == BigInt("36900")); } @safe unittest { import std.bigint; auto x = BigInt("1_000_000_500"); long l = 1_000_000L; ulong ul = 2_000_000UL; int i = 500_000; short s = 30_000; assert(is(typeof(x % l) == long) && x % l == 500L); assert(is(typeof(x % ul) == BigInt) && x % ul == BigInt(500)); assert(is(typeof(x % i) == int) && x % i == 500); assert(is(typeof(x % s) == int) && x % s == 10500); } @safe unittest { import std.bigint; auto x = BigInt("100"); BigInt y = 123 + x; assert(y == BigInt("223")); BigInt z = 123 - x; assert(z == BigInt("23")); // Dividing a built-in integer type by BigInt always results in // something that fits in a built-in type, so the built-in type is // returned, not BigInt. assert(is(typeof(1000 / x) == int)); assert(1000 / x == 10); } @safe unittest { import std.bigint; auto x = BigInt("1234"); assert(-x == BigInt("-1234")); ++x; assert(x == BigInt("1235")); } @safe unittest { import std.bigint; // Note that when comparing a BigInt to a float or double the // full precision of the BigInt is always considered, unlike // when comparing an int to a float or a long to a double. assert(BigInt(123456789) != cast(float) 123456789); } @safe unittest { import std.bigint; // Non-zero values are regarded as true auto x = BigInt("1"); auto y = BigInt("10"); assert(x); assert(y); // Zero value is regarded as false auto z = BigInt("0"); assert(!z); } @safe unittest { import std.bigint; import std.conv : to, ConvOverflowException; import std.exception : assertThrown; assert(BigInt("0").to!int == 0); assert(BigInt("0").to!ubyte == 0); assert(BigInt("255").to!ubyte == 255); assertThrown!ConvOverflowException(BigInt("256").to!ubyte); assertThrown!ConvOverflowException(BigInt("-1").to!ubyte); } @system unittest { import std.bigint; assert(cast(float) BigInt("35540592535949172786332045140593475584") == 35540592535949172786332045140593475584.0f); assert(cast(double) BigInt("35540601499647381470685035515422441472") == 35540601499647381470685035515422441472.0); assert(cast(real) BigInt("35540601499647381470685035515422441472") == 35540601499647381470685035515422441472.0L); assert(cast(float) BigInt("-0x1345_6780_0000_0000_0000_0000_0000") == -0x1.3456_78p+108f ); assert(cast(double) BigInt("-0x1345_678a_bcde_f000_0000_0000_0000") == -0x1.3456_78ab_cdefp+108 ); assert(cast(real) BigInt("-0x1345_678a_bcde_f000_0000_0000_0000") == -0x1.3456_78ab_cdefp+108L); } @system unittest { import std.bigint; // BigInts whose values cannot be exactly represented as float/double/real // are rounded when cast to float/double/real. When cast to float or // double or 64-bit real the rounding is strictly defined. When cast // to extended-precision real the rounding rules vary by environment. // BigInts that fall somewhere between two non-infinite floats/doubles // are rounded to the closer value when cast to float/double. assert(cast(float) BigInt(0x1aaa_aae7) == 0x1.aaa_aaep+28f); assert(cast(float) BigInt(0x1aaa_aaff) == 0x1.aaa_ab0p+28f); assert(cast(float) BigInt(-0x1aaa_aae7) == -0x1.aaaaaep+28f); assert(cast(float) BigInt(-0x1aaa_aaff) == -0x1.aaaab0p+28f); assert(cast(double) BigInt(0x1aaa_aaaa_aaaa_aa77) == 0x1.aaa_aaaa_aaaa_aa00p+60); assert(cast(double) BigInt(0x1aaa_aaaa_aaaa_aaff) == 0x1.aaa_aaaa_aaaa_ab00p+60); assert(cast(double) BigInt(-0x1aaa_aaaa_aaaa_aa77) == -0x1.aaa_aaaa_aaaa_aa00p+60); assert(cast(double) BigInt(-0x1aaa_aaaa_aaaa_aaff) == -0x1.aaa_aaaa_aaaa_ab00p+60); // BigInts that fall exactly between two non-infinite floats/doubles // are rounded away from zero when cast to float/double. (Note that // in most environments this is NOT the same rounding rule rule used // when casting int/long to float/double.) assert(cast(float) BigInt(0x1aaa_aaf0) == 0x1.aaa_ab0p+28f); assert(cast(float) BigInt(-0x1aaa_aaf0) == -0x1.aaaab0p+28f); assert(cast(double) BigInt(0x1aaa_aaaa_aaaa_aa80) == 0x1.aaa_aaaa_aaaa_ab00p+60); assert(cast(double) BigInt(-0x1aaa_aaaa_aaaa_aa80) == -0x1.aaa_aaaa_aaaa_ab00p+60); // BigInts that are bounded on one side by the largest positive or // most negative finite float/double and on the other side by infinity // or -infinity are rounded as if in place of infinity was the value // `2^^(T.max_exp)` when cast to float/double. assert(cast(float) BigInt("999_999_999_999_999_999_999_999_999_999_999_999_999") == float.infinity); assert(cast(float) BigInt("-999_999_999_999_999_999_999_999_999_999_999_999_999") == -float.infinity); assert(cast(double) BigInt("999_999_999_999_999_999_999_999_999_999_999_999_999") < double.infinity); assert(cast(real) BigInt("999_999_999_999_999_999_999_999_999_999_999_999_999") < real.infinity); } @safe unittest { import std.bigint; const(BigInt) x = BigInt("123"); BigInt y = cast() x; // cast away const assert(y == x); } @safe unittest { import std.bigint; auto x = BigInt("100"); auto y = BigInt("10"); int z = 50; const int w = 200; assert(y < x); assert(x > z); assert(z > y); assert(x < w); } @safe unittest { import std.bigint; auto x = BigInt("0x1abc_de80_0000_0000_0000_0000_0000_0000"); BigInt y = x - 1; BigInt z = x + 1; double d = 0x1.abcde8p124; assert(y < d); assert(z > d); assert(x >= d && x <= d); // Note that when comparing a BigInt to a float or double the // full precision of the BigInt is always considered, unlike // when comparing an int to a float or a long to a double. assert(BigInt(123456789) < cast(float) 123456789); } @safe unittest { import std.bigint; auto b = BigInt("12345"); long l = b.toLong(); assert(l == 12345); } @safe unittest { import std.bigint; auto big = BigInt("5_000_000"); auto i = big.toInt(); assert(i == 5_000_000); // Numbers that are too big to fit into an int will be clamped to int.max. auto tooBig = BigInt("5_000_000_000"); i = tooBig.toInt(); assert(i == int.max); } @safe unittest { import std.bigint; import std.format : format; auto x = BigInt("1_000_000"); x *= 12345; assert(format("%d", x) == "12345000000"); assert(format("%x", x) == "2_dfd1c040"); assert(format("%X", x) == "2_DFD1C040"); assert(format("%o", x) == "133764340100"); } @safe pure unittest { import std.bigint; string[BigInt] aa; aa[BigInt(123)] = "abc"; aa[BigInt(456)] = "def"; assert(aa[BigInt(123)] == "abc"); assert(aa[BigInt(456)] == "def"); } @safe pure unittest { import std.bigint; auto a = BigInt("1000"); assert(a.ulongLength() == 1); assert(a.getDigit(0) == 1000); assert(a.uintLength() == 1); assert(a.getDigit!uint(0) == 1000); auto b = BigInt("2_000_000_000_000_000_000_000_000_000"); assert(b.ulongLength() == 2); assert(b.getDigit(0) == 4584946418820579328); assert(b.getDigit(1) == 108420217); assert(b.uintLength() == 3); assert(b.getDigit!uint(0) == 3489660928); assert(b.getDigit!uint(1) == 1067516025); assert(b.getDigit!uint(2) == 108420217); } @safe unittest { import std.bigint; BigInt a = "9588669891916142"; BigInt b = "7452469135154800"; auto c = a * b; assert(c == BigInt("71459266416693160362545788781600")); auto d = b * a; assert(d == BigInt("71459266416693160362545788781600")); assert(d == c); d = c * BigInt("794628672112"); assert(d == BigInt("56783581982794522489042432639320434378739200")); auto e = c + d; assert(e == BigInt("56783581982865981755459125799682980167520800")); auto f = d + c; assert(f == e); auto g = f - c; assert(g == d); g = f - d; assert(g == c); e = 12345678; g = c + e; auto h = g / b; auto i = g % b; assert(h == a); assert(i == e); BigInt j = "-0x9A56_57f4_7B83_AB78"; BigInt k = j; j ^^= 11; assert(k ^^ 11 == j); } @safe pure unittest { import std.bigint; auto x = BigInt("123"); x *= 1000; x += 456; auto xstr = x.toDecimalString(); assert(xstr == "123456"); } @safe unittest { import std.bigint; auto x = BigInt("123"); x *= 1000; x += 456; auto xstr = x.toHex(); assert(xstr == "1E240"); } nothrow pure @safe unittest { import std.bigint; assert((-1).absUnsign == 1); assert(1.absUnsign == 1); } @safe pure nothrow unittest { import std.bigint; auto a = BigInt(123); auto b = BigInt(25); BigInt q, r; divMod(a, b, q, r); assert(q == 4); assert(r == 23); assert(q * b + r == a); } @safe unittest { import std.bigint; BigInt base = BigInt("123456789012345678901234567890"); BigInt exponent = BigInt("1234567890123456789012345678901234567"); BigInt modulus = BigInt("1234567"); BigInt result = powmod(base, exponent, modulus); assert(result == 359079); }