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