invert

Get base ^^ -1 (modulo mod).

Parameter mod must be positive.

pure nothrow @trusted
_MpZ!copyable
invert
(
bool copyable
)
(
auto ref const _MpZ!copyable base
,
auto ref const _MpZ!copyable mod
)

Examples

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

Meta