default construction
Z x; Z y; assert(x == y); assert(x is y); // TODO: is this correct behaviour? x = y; y = x; Z z = 42; x = z; assert(Z.init.dup == Z.init); assert(Z.init.dup == Z.init.dup); assert(Z.init.dup !is Z.init); assert(Z.init.dup !is Z.init.dup); Z w; w = 42;
@nogc to ASCII generation
Z w; auto chars = w.toChars; assert(chars == `0`); import core.memory : pureFree; pureFree(chars.ptr);
operate on default-constructed instances
1 Z w; 2 3 // should be zeroed 4 assert(w._z._mp_alloc == 0); 5 assert(w._z._mp_size == 0); 6 assert(w._z._mp_d is null); 7 8 assert(w == 0); 9 assert(w == 0L); 10 assert(w == 0UL); 11 assert(w == 0.0f); 12 assert(w == 0.0); 13 14 assert(w.toString == `0`); 15 assert(w.toHash == 0); 16 assert(w.sizeInBase(10) == 1); 17 assert(w.countOnes == 0); 18 assert(w.isZero); 19 assert(-w == w); 20 assert(abs(w) == w); 21 22 assert(w.fitsIn!ulong); 23 assert(w.fitsIn!long); 24 assert(w.fitsIn!uint); 25 assert(w.fitsIn!int); 26 assert(w.fitsIn!ushort); 27 assert(w.fitsIn!short); 28 29 assert(!w.isOdd); 30 assert(w.isEven); 31 assert(!w.isNegative); 32 assert(w.isPositive); 33 assert(w.sgn == 0); 34 35 w.negate(); 36 assert(w is Z.init); // should be unchanged 37 w.negate(); 38 assert(w is Z.init); // should be unchanged 39 40 w = -w; 41 assert(w is Z.init); // should be unchanged 42 43 w = +w; 44 assert(w is Z.init); // should be unchanged 45 46 w.absolute(); 47 assert(w is Z.init); // should be unchanged 48 49 w.onesComplement(); 50 assert(w is Z.init); // should be unchanged 51 w.onesComplement(); 52 assert(w is Z.init); // should be unchanged 53 54 assert(w^^10 == 0); 55 assert(w^^0 == 1); // TODO: correct? 56 57 // change it and check its contents 58 w = 42; 59 assert(w.toString == `42`); 60 assert(w.toHash != 0); // should at least be non-zero 61 62 { 63 Z p; 64 p.setBit(5); 65 assert(p == 32); 66 } 67 { 68 Z p; 69 p.clearBit(5); 70 assert(p == 0); 71 } 72 { 73 Z p; 74 p.complementBit(5); 75 assert(p == 32); 76 } 77 { 78 Z p; 79 assert(p.testBit(5) == 0); 80 } 81 { 82 Z p; 83 ++p; 84 assert(p == 1); 85 } 86 { 87 Z p; 88 --p; 89 assert(p == -1); 90 } 91 92 assert(Z.init + Z.init == Z.init); 93 assert(Z.init - Z.init == Z.init); 94 assert(Z.init * Z.init == Z.init); 95 96 assert(Z.init + 1 == 1); 97 assert(Z.init - 1 == -1); 98 99 assert(Z.init * 1 == 0); 100 assert(Z.init / 1 == 0); 101 assert(Z.init ^^ 1 == Z.init); 102 assert(Z.init ^^ 0 == 1); 103 104 assert(1 + Z.init == 1); 105 assert(1 - Z.init == 1); 106 assert(1 * Z.init == 0);
null construction
Z x = null; Z y = null; assert(x == y); assert(x is y); // TODO: this behaviour recently changed. is this correct?
const x = 42.Z; assert(x.unaryMinus() == -42); // l-value `this` assert(42.Z.unaryMinus() == -42); // r-value `this`
convert to string
assert(mpz( 42).toString == `42`); assert(mpz( -42).toString == `-42`); assert(mpz(`-101`).toString == `-101`); assert(mpz(-42).toDecimalString == `-42`); assert(mpz( 42).toDecimalString == `42`); assert(mpz( 0).toHex == `0`); assert(mpz( 1).toHex == `1`); assert(mpz( 9).toHex == `9`); assert(mpz(10).toHex == `A`); assert(mpz(14).toHex == `E`); assert(mpz(15).toHex == `F`); assert(mpz(16).toHex == `10`); assert(mpz(-42).absUnsign!ulong == 42); assert(mpz( 42).absUnsign!ulong == 42);
ubyte[int.sizeof] storage; ubyte[1] expected = [2]; assert(storage[0] == 0); auto storage2 = 2.Z.serialize(storage, WordOrder.mostSignificantWordFirst, 1, WordEndianess.littleEndian, 0); assert(storage2.ptr == storage.ptr); assert(storage2 == expected);
auto prime = 33391.Z; for (int i = 0; i < 20; ++i) { prime = nextPrime(prime); for (auto order = WordOrder.min; order < WordOrder.max; ++order) { for (auto endianess = WordEndianess.min; endianess < WordEndianess.max; ++endianess) { ubyte[] data = prime.serialize!(ubyte)(order, endianess, 0); auto samePrime = Z(data, order, 1, endianess, 0); assert(prime == samePrime); } } }
opBinary with r-value right-hand-side
Z a = 42; { Z b = a + 1.Z; // r-value `rhs` version(ccc) assert(b.mutatingCallCount == 2); assert(b == 43); } { Z b = a - 1.Z; // r-value `rhs` version(ccc) assert(b.mutatingCallCount == 2); assert(b == 41); } { Z b = a * 2.Z; // r-value `rhs` version(ccc) assert(b.mutatingCallCount == 2); assert(b == 84); } { Z b = a / 2.Z; // r-value `rhs` version(ccc) assert(b.mutatingCallCount == 2); assert(b == 21); } { Z b = a % 10.Z; // r-value `rhs` version(ccc) assert(b.mutatingCallCount == 2); assert(b == 2); }
1 const _ = (cast(uint)42).Z; 2 const a = 42.Z; 3 const b = 43UL.Z; 4 const c = 43.0.Z; 5 const z = 0.Z; 6 7 // `opOpAssign` with `Unsigned` 8 auto w = 42.Z; 9 assert(w == 42); 10 11 w += 100UL; 12 assert(w == 142); 13 14 w -= 100.Z; 15 assert(w == 42); 16 17 w += 100UL; 18 assert(w == 142); 19 20 w -= 100UL; 21 assert(w == 42); 22 23 w *= 100UL; 24 assert(w == 4200); 25 26 w /= 100UL; 27 assert(w == 42); 28 29 w %= 10UL; 30 assert(w == 2); 31 32 w ^^= 6UL; 33 assert(w == 64); 34 35 w = 42; 36 assert(w == 42); 37 38 w += 100; 39 assert(w == 142); 40 41 w -= 100; 42 assert(w == 42); 43 44 w *= 100; 45 assert(w == 4200); 46 47 w /= 100; 48 assert(w == 42); 49 50 w *= 100; 51 assert(w == 4200); 52 53 w /= -100; 54 assert(w == -42); 55 56 w *= -1; 57 assert(w == 42); 58 59 w %= 10; 60 assert(w == 2); 61 62 w = 2; 63 w ^^= 6; 64 assert(w == 64); 65 66 w = 32.0; 67 assert(w == 32); 68 69 w = 42UL; 70 assert(w == 42); 71 72 w /= 2.Z; 73 assert(w == 21); 74 75 w /= -2.Z; 76 assert(w == -10); 77 78 w *= -2.Z; 79 assert(w == 20); 80 81 w %= 3.Z; 82 assert(w == 2); 83 84 w *= -1.Z; 85 assert(w == -2); 86 87 w /= -1.Z; 88 assert(w == 2); 89 90 // equality 91 assert(z == 0); 92 assert(z == cast(uint)0); 93 assert(z == 0L); 94 assert(z == 0UL); 95 assert(z == 0.0f); 96 assert(z == 0.0); 97 98 // eval cast 99 100 assert(a); 101 assert(cast(ulong)a == a); 102 assert(cast(ulong)a == 42); 103 assert(cast(long)a == a); 104 assert(cast(long)a == 42); 105 assert(cast(double)a == 42.0); 106 107 // binary 108 109 assert(`0b11`.Z == 3); 110 assert(`0B11`.Z == 3); 111 112 // octal 113 114 assert(`07`.Z == 7); 115 assert(`010`.Z == 8); 116 117 // hexadecimal 118 119 assert(`0x10`.Z == 16); 120 assert(`0X10`.Z == 16); 121 122 // decimal 123 124 assert(`101`.Z == 101); 125 assert(`101`.Z == 101); 126 127 const ic = 101UL.Z; 128 129 assert(a == a.dup); 130 assert(ic == ic.dup); 131 132 // equality 133 134 assert(a == a); 135 assert(a == 42.Z); 136 assert(a == 42.0); 137 assert(a == 42); 138 assert(a == cast(uint)42); 139 assert(a == 42UL); 140 assert(_ == 42); 141 assert(c == 43.0); 142 143 // non-equality 144 145 assert(a != b); 146 147 // less than 148 149 assert(a < b); 150 assert(a < 43.Z); 151 assert(a < 43); 152 assert(a < cast(uint)43); 153 assert(a < 43UL); 154 assert(a < 43.0); 155 156 assert(-1.Z < 0.Z); 157 assert(-1.Z < 0L); 158 assert(-1.Z < 0UL); 159 assert(-1.Z < 0.0); 160 161 // greater than 162 163 assert(b > a); 164 assert(b > 42.Z); 165 assert(b > 42); 166 assert(b > cast(uint)42); 167 assert(b > 42UL); 168 assert(b > 42.0); 169 170 assert(+1.Z > 0.Z); 171 assert(+1.Z > 0L); 172 assert(+1.Z > 0UL); 173 assert(+1.Z > 0.0); 174 175 // absolute value 176 177 assert(abs(a) == a); // free function 178 assert(a.abs == a); // UFCS 179 assert(abs(-42.Z) == 42); 180 assert(abs(-a) == a); 181 182 // absolute value comparison 183 184 assert(cmpabs(-43.Z, 44.Z) == -1); 185 assert(cmpabs(-43.Z, -44.Z) == -1); 186 assert(cmpabs(-44.Z, -43.Z) == +1); 187 assert(cmpabs(-43.Z, -43.Z) == 0); 188 189 assert(cmpabs(-43.Z, 44.0) == -1); 190 assert(cmpabs(-43.Z, -44.0) == -1); 191 assert(cmpabs(-44.Z, -43.0) == +1); 192 assert(cmpabs(-43.Z, -43.0) == 0); 193 194 assert(cmpabs(-43.Z, 44) == -1); 195 assert(cmpabs( 43.Z, 44) == -1); 196 assert(cmpabs(-44.Z, 43) == +1); 197 assert(cmpabs( 44.Z, 43) == +1); 198 assert(cmpabs(-43.Z, 43) == 0); 199 200 Z _43 = 43; 201 Z _4 = 4; 202 Z _24 = 24; 203 204 // next prime 205 assert(nextPrime(_4) == 5); 206 assert(nextPrime(24.Z) == 29); 207 208 assert(nextPrime(_24) == 29); 209 assert(nextPrime(24.Z) == 29); 210 assert(24.Z.nextPrime() == 29); 211 212 assert(nextPrime(_43) == 47); 213 assert(nextPrime(43.Z) == 47); 214 assert(43.Z.nextPrime() == 47); 215 216 // greatest common divisor 217 218 assert(gcd(43.Z, 44.Z) == 1); 219 assert(gcd(4.Z, 24.Z) == 4); 220 assert(gcd(6.Z, 24.Z) == 6); 221 assert(gcd(10.Z, 100.Z) == 10); 222 223 assert(gcd(43.Z, 44) == 1); 224 assert(gcd(4.Z, 24) == 4); 225 assert(gcd(6.Z, 24) == 6); 226 assert(gcd(10.Z, 100) == 10); 227 228 assert(gcd(_43, 44) == 1); 229 assert(gcd(_4, 24) == 4); 230 assert(gcd(_4, _24) == 4); 231 assert(gcd(_4, 24.Z) == 4); 232 233 // least common multiple 234 235 assert(lcm(43.Z, 44.Z) == 1892); 236 assert(lcm(4.Z, 24.Z) == 24); 237 assert(lcm(6.Z, 24.Z) == 24); 238 assert(lcm(10.Z, 100.Z) == 100); 239 240 assert(lcm(43.Z, 44) == 1892); 241 assert(lcm(4.Z, 24) == 24); 242 assert(lcm(6.Z, 24) == 24); 243 assert(lcm(10.Z, 100) == 100); 244 245 assert(lcm(_43, 44) == 1892); 246 assert(lcm(_4, 24) == 24); 247 assert(lcm(_4, _24) == 24); 248 assert(lcm(_4, 24.Z) == 24); 249 250 // negated value 251 252 assert(-a == -42); 253 assert(-(-a) == a); 254 255 auto n = 42.Z; 256 n.negate(); 257 assert(n == -42); 258 n.negate(); 259 assert(n == 42); 260 n.negate(); 261 assert(n == -42); 262 n.absolute(); 263 assert(n == 42); 264 n.absolute(); 265 assert(n == 42); 266 267 n.onesComplement(); 268 assert(n == -43); 269 assert(onesComplement(n) == 42); 270 assert(onesComplement(-43.Z) == 42); 271 272 // addition 273 274 assert(a + b == b + a); // commutative 275 assert(a + 43.Z == b + a); 276 assert(a - 43.Z == -(43.Z - a)); 277 assert(a + 0 == a); 278 assert(a + 1 != a); 279 assert(0 + a == a); 280 assert(1 + a != a); 281 assert(a + 0UL == a); 282 assert(a + 1UL != a); 283 assert(a + b == 42 + 43); 284 assert(1 + a == 43); 285 assert(a + (-1) == 41); 286 assert(1UL + a == 43); 287 assert(a + 1 == 1 + a); // commutative 288 assert(a + (-1) == (-1) + a); // commutative 289 assert(1UL + a == a + 1UL); // commutative 290 291 // subtraction 292 293 assert(a - 2 == 40); 294 assert(2 - a == -40); 295 assert(-2 - a == -44); 296 assert(a - 2 == -(2 - a)); // commutative 297 assert(a - (-2) == 44); 298 assert(44UL - 42.Z == 2); 299 300 // multiplication 301 302 assert(a * 1UL == a); 303 assert(a * 1 == a); 304 assert(1 * a == a); 305 assert(1UL * a == a); 306 assert((-1) * a == -a); 307 assert(a * 2 != a); 308 assert(a * -2 == -(2*a)); 309 assert(a * b == b * a); 310 assert(a * b == 42UL * 43UL); 311 312 // division 313 314 assert(27.Z / 3.Z == 9); 315 assert(27.Z / 3 == 9); 316 317 assert(27.Z / 10.Z == 2); 318 assert(27.Z / 10 == 2); 319 assert(27.Z / 10UL == 2); 320 321 assert(27.Z / -3 == -9); 322 assert(27.Z / 3UL == 9); 323 324 assert(27.Z / -10 == -2); 325 326 assert(28 / 3.Z == 9); 327 assert(28UL / 3.Z == 9); 328 329 assert(28 / -3.Z == -9); 330 assert(28UL / -3.Z == -9); 331 332 // modulo/remainder 333 334 assert(27.Z % 3.Z == 0); 335 assert(27.Z % 10.Z == 7); 336 337 assert(27.Z % 3 == 0); 338 assert(-27.Z % 3 == 0); 339 340 assert(27.Z % 10 == 7); 341 assert(27.Z % 10 == 7); 342 343 assert(28 % 3.Z == 1); 344 assert(28UL % 3.Z == 1); 345 346 assert( 28.Z % -3 == -1); // negative divisor gives negative remainder according to https://en.wikipedia.org/wiki/Remainder 347 assert(-28.Z % 3 == 1); // dividend sign doesn't affect remainder 348 349 // 350 assert( 28.Z % -3.Z == 1); // TODO: should be -1 351 assert(-28.Z % 3.Z == -1); // TODO: should be 1 352 assert( 28 % -3.Z == 1); // TODO: should be -1 353 assert(-28 % 3.Z == -1); // TODO: should be 1 354 355 // modulo/remainder 356 357 const one = 1.Z; 358 const two = 2.Z; 359 const three = 3.Z; 360 const four = 4.Z; 361 const five = 5.Z; 362 const six = 6.Z; 363 assert(six % one == 0); 364 assert(six % two == 0); 365 assert(six % three == 0); 366 assert(six % four == 2); 367 assert(six % five == 1); 368 assert(six % six == 0); 369 370 // subtraction 371 372 assert(six - one == 5); 373 assert(six - 1UL == 5); 374 assert(six - 1 == 5); 375 assert(1 - six == -5); 376 assert(1L - six == -5); 377 assert(1UL - six == -5); 378 379 // exponentiation 380 assert(0.Z^^0 == 1); 381 assert(3.Z^^3 == 27); 382 assert(3.Z^^3L == 27); 383 assert(2.Z^^8 == 256); 384 assert(2.Z^^8L == 256); 385 assert(2.Z^^8UL == 256); 386 387 assert(Z.pow(2UL, 8UL) == 256); 388 assert(Z.pow(2UL, 8) == 256); 389 assert(Z.pow(2UL, 8) == 256); 390 assert(Z.pow(2, 8) == 256); 391 assert(Z.pow(-2, 8) == 256); 392 assert(Z.pow(-2, 7) == -128); 393 394 // disallow power exponent to be an `MpZ` 395 assert(!__traits(compiles, 2^^8.Z == 256)); 396 assert(!__traits(compiles, 2L^^8.Z == 256)); 397 assert(!__traits(compiles, 2UL^^8.Z == 256)); 398 399 // exponentiation plus modulus 400 401 assert(2.Z.powm(8.Z, 8.Z) == 0.Z); 402 assert(2.Z.powm(3.Z, 16.Z) == 8.Z); 403 assert(3.Z.powm(3.Z, 16.Z) == 11.Z); 404 405 assert(2.Z.powm(8, 8.Z) == 0.Z); 406 assert(2.Z.powm(3, 16.Z) == 8.Z); 407 assert(3.Z.powm(3, 16.Z) == 11.Z); 408 409 // modular multiplicative inverse 410 assert(3.Z.invert(26.Z) == 9.Z); // r-value `base` 411 assert(3.Z.invert(-26.Z) == 9.Z); // r-value `base` 412 { 413 auto base = 3.Z; 414 assert(base.invert(26.Z) == 9.Z); // l-value `base` and r-value `mod` 415 } 416 { 417 auto base = 3.Z; 418 auto mod = 26.Z; 419 assert(base.invert(mod) == 9.Z); // l-value `base` and l-value `mod 420 } 421 422 // bitwise and, or and xor 423 424 { 425 foreach (immutable i; 0 .. 10) 426 { 427 foreach (immutable j; 0 .. 10) 428 { 429 assert((i.Z & j.Z) == (i & j)); 430 assert((i.Z | j.Z) == (i | j)); 431 assert((i.Z ^ j.Z) == (i ^ j)); 432 433 Z x = null; 434 435 x = i.Z; 436 x &= j.Z; 437 assert(x == (i & j)); 438 439 x = i.Z; 440 x |= j.Z; 441 assert(x == (i | j)); 442 443 x = i.Z; 444 x ^= j.Z; 445 assert(x == (i ^ j)); 446 } 447 } 448 } 449 450 // swap 451 452 auto x = 42.Z; 453 auto y = 43.Z; 454 455 assert(x == 42); 456 assert(y == 43); 457 458 x.swap(y); 459 460 assert(y == 42); 461 assert(x == 43); 462 463 swap(x, y); 464 465 assert(x == 42); 466 assert(y == 43); 467 468 assert(null.Z.fromString("42") == 42.Z); 469 assert(null.Z.fromString("42") < 43.Z); 470 assert(null.Z.fromString("42") > 41.Z); 471 assert(null.Z.fromString("42") == 42); 472 assert(null.Z.fromString("11", 2) == 3); 473 assert(null.Z.fromString("7", 8) == 7); 474 assert(null.Z.fromString("7") == 7); 475 assert(null.Z.fromString("e", 16) == 14); 476 assert(null.Z.fromString("f", 16) == 15); 477 assert(null.Z.fromString("0xe") == 14); 478 assert(null.Z.fromString("0xf") == 15); 479 assert(null.Z.fromString("10", 16) == 16); 480 assert(null.Z.fromString("10", 32) == 32); 481 482 // odd and even 483 484 assert(0.Z.isEven); 485 assert(1.Z.isOdd); 486 assert(2.Z.isEven); 487 assert(3.Z.isOdd); 488 489 assert((-1).Z.isOdd); 490 assert((-2).Z.isEven); 491 assert((-3).Z.isOdd); 492 493 assert("300000000000000000000000000000000000000".Z.isEven); 494 assert("300000000000000000000000000000000000001".Z.isOdd); 495 assert("300000000000000000000000000000000000002".Z.isEven); 496 assert("300000000000000000000000000000000000003".Z.isOdd); 497 498 // negative and positive 499 500 assert(0.Z.isPositive); 501 assert(1.Z.isPositive); 502 assert(2.Z.isPositive); 503 assert(3.Z.isPositive); 504 505 assert((-1).Z.isNegative); 506 assert((-2).Z.isNegative); 507 assert((-3).Z.isNegative); 508 509 // sign function (sgn) 510 511 assert(long.min.Z.sgn == -1); 512 assert(int.min.Z.sgn == -1); 513 assert(-2.Z.sgn == -1); 514 assert(-1.Z.sgn == -1); 515 assert( 0.Z.sgn == 0); 516 assert( 1.Z.sgn == 1); 517 assert( 2.Z.sgn == 1); 518 assert(int.max.Z.sgn == 1); 519 assert(long.max.Z.sgn == 1); 520 521 assert(!long.min.Z.isZero); 522 assert(!int.min.Z.isZero); 523 assert(!(-2).Z.isZero); 524 assert(!(-1).Z.isZero); 525 assert( 0.Z.isZero); 526 assert(! 1.Z.isZero); 527 assert(! 2.Z.isZero); 528 assert(!int.max.Z.isZero); 529 assert(!long.max.Z.isZero); 530 531 assert(1.Z.populationCount == 1); 532 assert(2.Z.populationCount == 1); 533 assert(3.Z.populationCount == 2); 534 assert(4.Z.populationCount == 1); 535 assert(5.Z.populationCount == 2); 536 assert(6.Z.populationCount == 2); 537 assert(7.Z.populationCount == 3); 538 539 // TODO 540 // { 541 // Z g = null; 542 // assert(!b.testBit(0)); 543 // g.setBit(0); 544 // assert(b.testBit(0)); 545 // g.clearBit(0); 546 // assert(!b.testBit(0)); 547 // } 548 549 // fits in type 550 551 foreach (Integral; AliasSeq!(short, int, long, 552 ushort, uint, ulong)) 553 { 554 assert(Integral.min.Z.fitsIn!Integral); 555 assert(Integral.max.Z.fitsIn!Integral); 556 } 557 558 // TODO 559 // assert(short.min.Z.fitsIn!short); 560 // assert(short.max.Z.fitsIn!short); 561 // assert(ushort.min.Z.fitsIn!ushort); 562 // assert(ushort.max.Z.fitsIn!ushort); 563 564 // limb count 565 566 assert(0.Z.limbCount == 0); 567 assert(1.Z.limbCount == 1); 568 assert(2.Z.limbCount == 1); 569 570 assert(Z.pow(2UL, 32UL).limbCount == 1); 571 572 assert(Z.pow(2UL, 63UL).limbCount == 1); 573 assert(Z.pow(2UL, 63UL + 1).limbCount == 2); 574 575 assert(Z.pow(2UL, 127UL).limbCount == 2); 576 assert(Z.pow(2UL, 127UL + 1).limbCount == 3); 577 578 assert(Z.pow(2UL, 255UL).limbCount == 4); 579 assert(Z.pow(2UL, 255UL + 1).limbCount == 5);
generators
assert(Z.mersennePrime(15) == 2^^15 - 1); assert(Z.mersennePrime(15UL) == 2^^15 - 1);
left shift
assert(1.Z << 1.Z == 2^^1); assert(1.Z << 2.Z == 2^^2); assert(1.Z << 32.Z == 2UL^^32); assert(1.Z << 63.Z == 2UL^^63); assert(1.Z << 1U == 2^^1); assert(1.Z << 2U == 2^^2); assert(1.Z << 32U == 2UL^^32); assert(1.Z << 63U == 2UL^^63);
verify compliance with Phobos' BigInt
1 alias bigInt = mpz; 2 alias BigInt = Z; // Phobos naming convention 3 4 { 5 const BigInt a = "9588669891916142"; 6 const BigInt b = "7452469135154800"; 7 const c = a * b; 8 assert(c == BigInt("71459266416693160362545788781600")); 9 auto d = b * a; 10 assert(d == BigInt("71459266416693160362545788781600")); 11 assert(d == c); 12 d = c * BigInt("794628672112"); 13 assert(d == BigInt("56783581982794522489042432639320434378739200")); 14 auto e = c + d; 15 assert(e == BigInt("56783581982865981755459125799682980167520800")); 16 const f = d + c; 17 assert(f == e); 18 auto g = f - c; 19 assert(g == d); 20 g = f - d; 21 assert(g == c); 22 e = 12_345_678; 23 g = c + e; 24 const h = g / b; 25 const i = g % b; 26 assert(h == a); 27 assert(i == e); 28 BigInt j = "-0x9A56_57f4_7B83_AB78"; 29 j ^^= 11UL; 30 j ^^= 2L; 31 j ^^= 2; 32 } 33 34 { 35 auto b = BigInt("1_000_000_000"); 36 37 b += 12_345; 38 assert(b == 1_000_012_345); 39 b += -12_345; 40 assert(b == 1_000_000_000); 41 42 b -= -12_345; 43 assert(b == 1_000_012_345); 44 b -= +12_345; 45 assert(b == 1_000_000_000); 46 47 b += 12_345; 48 assert(b == 1_000_012_345); 49 50 b /= 5UL; 51 assert(b == 200_002_469); 52 } 53 54 { 55 auto x = BigInt("123"); 56 const y = BigInt("321"); 57 x += y; 58 assert(x == 444); 59 } 60 61 { 62 const x = BigInt("123"); 63 const y = BigInt("456"); 64 const BigInt z = x * y; 65 assert(z == 56_088); 66 } 67 68 { 69 auto x = BigInt("123"); 70 x *= 300; 71 assert(x == 36_900); 72 } 73 74 { 75 auto x = BigInt("123"); 76 x *= -1; 77 assert(x == -123); 78 } 79 80 { 81 const x = BigInt("1_000_000_500"); 82 83 immutable ulong ul = 2_000_000UL; 84 immutable uint ui = 500_000; 85 immutable ushort us = 30_000; 86 immutable ubyte ub = 50; 87 88 immutable long l = 1_000_000L; 89 immutable int i = 500_000; 90 immutable short s = 30_000; 91 immutable byte b = 50; 92 93 static assert(is(typeof(x % ul) == ulong)); 94 static assert(is(typeof(x % ui) == uint)); 95 static assert(is(typeof(x % us) == ushort)); 96 static assert(is(typeof(x % ub) == ubyte)); 97 98 static assert(is(typeof(x % l) == long)); 99 static assert(is(typeof(x % i) == int)); 100 // TODO: static assert(is(typeof(x % s) == short)); 101 // TODO: static assert(is(typeof(x % b) == byte)); 102 103 assert(x % ul == 500); 104 assert(x % ui == 500); 105 assert(x % us == 10_500); 106 assert(x % ub == 0); 107 108 assert(x % l == 500L); 109 assert(x % i == 500); 110 assert(x % s == 10_500); 111 assert(x % b == 0); 112 } 113 114 { 115 const x = BigInt("100"); 116 const BigInt y = 123 + x; 117 assert(y == BigInt("223")); 118 119 const BigInt z = 123 - x; 120 assert(z == BigInt("23")); 121 122 // Dividing a built-in integer type by BigInt always results in 123 // something that fits in a built-in type, so the built-in type is 124 // returned, not BigInt. 125 static assert(is(typeof(1000 / x) == int)); 126 assert(1000 / x == 10); 127 } 128 129 { 130 auto x = BigInt("1234"); 131 assert(+x == BigInt(" 1234")); 132 assert(-x == BigInt("-1234")); 133 ++x; 134 assert(x == BigInt("1235")); 135 --x; 136 assert(x == BigInt("1234")); 137 } 138 139 { 140 const x = BigInt("12345"); 141 const y = BigInt("12340"); 142 immutable int z = 12_345; 143 immutable int w = 54_321; 144 assert(x == x); 145 assert(x != y); 146 assert(x == y + 5); 147 assert(x == z); 148 assert(x != w); 149 } 150 151 { 152 // non-zero values are regarded as `true` 153 const x = BigInt("1"); 154 const y = BigInt("10"); 155 assert(x); 156 assert(y); 157 158 // zero value is regarded as `false` 159 const z = BigInt("0"); 160 assert(!z); 161 } 162 163 { 164 assert(cast(int)BigInt("0") == 0); 165 assert(cast(ubyte)BigInt("0") == 0); 166 167 assert(cast(ubyte)BigInt(255) == 255); 168 assert(cast(ushort)BigInt(65_535) == 65_535); 169 assert(cast(uint)BigInt(uint.max) == uint.max); 170 assert(cast(ulong)BigInt(ulong.max) == ulong.max); 171 172 assert(cast(byte)BigInt(-128) == -128); 173 assert(cast(short)BigInt(-32_768) == -32_768); 174 assert(cast(int)BigInt(int.min) == int.min); 175 assert(cast(long)BigInt(long.min) == long.min); 176 177 assert(cast(byte)BigInt(127) == 127); 178 assert(cast(short)BigInt(32_767) == 32_767); 179 assert(cast(int)BigInt(int.max) == int.max); 180 assert(cast(long)BigInt(long.max) == long.max); 181 182 // TODO: 183 // import std.conv : to, ConvOverflowException; 184 // import std.exception : assertThrown; 185 // assertThrown!ConvOverflowException(BigInt("256").to!ubyte); 186 // assertThrown!ConvOverflowException(BigInt("-1").to!ubyte); 187 } 188 189 { 190 // TODO 191 // segfaults because with double free 192 // const(BigInt) x = BigInt("123"); 193 // BigInt y = cast()x; // cast away const 194 // assert(y == x); 195 } 196 197 { 198 const x = BigInt("100"); 199 const y = BigInt("10"); 200 const int z = 50; 201 const int w = 200; 202 assert(y < x); 203 assert(x > z); 204 assert(z > y); 205 assert(x < w); 206 } 207 208 { 209 assert(BigInt("12345").toLong() == 12_345); 210 assert(BigInt("-123450000000000000000000000000").toLong() == long.min); 211 assert(BigInt("12345000000000000000000000000000").toLong() == long.max); 212 } 213 214 { 215 assert(BigInt("12345").toInt() == 12_345); 216 assert(BigInt("-123450000000000000000000000000").toInt() == int.min); 217 assert(BigInt("12345000000000000000000000000000").toInt() == int.max); 218 }
Fermats Little Theorem
version (unittestLong) { /* Fermats little theorem: a ^ p ≡ a (mod p) ∀ prime p check Fermats little theorem for a ≤ 100000 and all mersene primes M(p) : p ≤ 127 */ foreach (immutable ulong i; [2, 3, 5, 7, 13, 17, 19, 31, 61, 89, 107, 127]) { foreach (immutable ulong j; 2 .. 100_000) { const p = Z.mersennePrime(i); // power const a = Z(j); // base const amp = a % p; const b = a.powm(p, p); // result assert(b == amp); } } }
Get base ^^ -1 (modulo mod).
Parameter mod must be positive.