1 /** Arbitrary-precision ('bignum') arithmetic.
2  *
3  * Performance is optimized for numbers below ~1000 decimal digits.
4  * For X86 machines, highly optimised assembly routines are used.
5  *
6  * The following algorithms are currently implemented:
7  * $(UL
8  * $(LI Karatsuba multiplication)
9  * $(LI Squaring is optimized independently of multiplication)
10  * $(LI Divide-and-conquer division)
11  * $(LI Binary exponentiation)
12  * )
13  *
14  * For very large numbers, consider using the $(HTTP gmplib.org, GMP library) instead.
15  *
16  * License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
17  * Authors:   Don Clugston
18  * Source: $(PHOBOSSRC std/bigint.d)
19  */
20 /*          Copyright Don Clugston 2008 - 2010.
21  * Distributed under the Boost Software License, Version 1.0.
22  *    (See accompanying file LICENSE_1_0.txt or copy at
23  *          http://www.boost.org/LICENSE_1_0.txt)
24  */
25 
26 module std.bigint;
27 
28 import std.conv : ConvException;
29 
30 import std.format.spec : FormatSpec;
31 import std.format : FormatException;
32 import std.internal.math.biguintcore;
33 import std.internal.math.biguintnoasm : BigDigit;
34 import std.range.primitives;
35 import std.traits;
36 
37 /** A struct representing an arbitrary precision integer.
38  *
39  * All arithmetic operations are supported, except unsigned shift right (`>>>`).
40  * Bitwise operations (`|`, `&`, `^`, `~`) are supported, and behave as if BigInt was
41  * an infinite length 2's complement number.
42  *
43  * BigInt implements value semantics using copy-on-write. This means that
44  * assignment is cheap, but operations such as x++ will cause heap
45  * allocation. (But note that for most bigint operations, heap allocation is
46  * inevitable anyway.)
47  */
48 struct BigInt
49 {
50 private:
51     BigUint data;     // BigInt adds signed arithmetic to BigUint.
52     bool sign = false;
53 public:
54     /**
55      * Construct a `BigInt` from a decimal or hexadecimal string. The number must
56      * be in the form of a decimal or hex literal. It may have a leading `+`
57      * or `-` sign, followed by `0x` or `0X` if hexadecimal. Underscores are
58      * permitted in any location after the `0x` and/or the sign of the number.
59      *
60      * Params:
61      *     s = a finite bidirectional range of any character type
62      *
63      * Throws:
64      *     $(REF ConvException, std,conv) if the string doesn't represent a valid number
65      */
66     this(Range)(Range s)
67     if (isBidirectionalRange!Range &&
68         isSomeChar!(ElementType!Range) &&
69         !isInfinite!Range &&
70         !isNarrowString!Range)
71     {
72         import std.algorithm.iteration : filterBidirectional;
73         import std.algorithm.searching : startsWith;
74         import std.conv : ConvException;
75         import std.exception : enforce;
76         import std.utf : byChar;
77 
78         enforce!ConvException(!s.empty, "Can't initialize BigInt with an empty range");
79 
80         bool neg = false;
81         bool ok;
82 
83         data = 0UL;
84 
85         // check for signs and if the string is a hex value
86         if (s.front == '+')
87         {
88             s.popFront(); // skip '+'
89         }
90         else if (s.front == '-')
91         {
92             neg = true;
93             s.popFront();
94         }
95 
96         if (s.save.startsWith("0x".byChar) ||
97             s.save.startsWith("0X".byChar))
98         {
99             s.popFront;
100             s.popFront;
101 
102             if (!s.empty)
103                 ok = data.fromHexString(s.filterBidirectional!(a => a != '_'));
104             else
105                 ok = false;
106         }
107         else
108         {
109             ok = data.fromDecimalString(s.filterBidirectional!(a => a != '_'));
110         }
111 
112         enforce!ConvException(ok, "Not a valid numerical string");
113 
114         if (isZero())
115             neg = false;
116 
117         sign = neg;
118     }
119 
120     /// ditto
121     this(Range)(Range s) pure
122     if (isNarrowString!Range)
123     {
124         import std.utf : byCodeUnit;
125         this(s.byCodeUnit);
126     }
127 
128     @safe unittest
129     {
130         // system because of the dummy ranges eventually call std.array!string
131         import std.exception : assertThrown;
132         import std.internal.test.dummyrange;
133 
134         auto r1 = new ReferenceBidirectionalRange!dchar("101");
135         auto big1 = BigInt(r1);
136         assert(big1 == BigInt(101));
137 
138         auto r2 = new ReferenceBidirectionalRange!dchar("1_000");
139         auto big2 = BigInt(r2);
140         assert(big2 == BigInt(1000));
141 
142         auto r3 = new ReferenceBidirectionalRange!dchar("0x0");
143         auto big3 = BigInt(r3);
144         assert(big3 == BigInt(0));
145 
146         auto r4 = new ReferenceBidirectionalRange!dchar("0x");
147         assertThrown!ConvException(BigInt(r4));
148     }
149 
150     /**
151      * Construct a `BigInt` from a sign and a magnitude.
152      *
153      * The magnitude is an $(REF_ALTTEXT input range, isInputRange, std,range,primitives)
154      * of unsigned integers that satisfies either $(REF hasLength, std,range,primitives)
155      * or $(REF isForwardRange, std,range,primitives). The first (leftmost)
156      * element of the magnitude is considered the most significant.
157      *
158      * Params:
159      *     isNegative = true for negative, false for non-negative
160      *          (ignored when magnitude is zero)
161      *     magnitude = a finite range of unsigned integers
162      */
163     this(Range)(bool isNegative, Range magnitude)
164     if (isInputRange!Range &&
165         isUnsigned!(ElementType!Range) &&
166         (hasLength!Range || isForwardRange!Range) &&
167         !isInfinite!Range)
168     {
169         data.fromMagnitude(magnitude);
170         sign = isNegative && !data.isZero;
171     }
172 
173     ///
174     pure @safe unittest
175     {
176         ubyte[] magnitude = [1, 2, 3, 4, 5, 6];
177         auto b1 = BigInt(false, magnitude);
178         assert(cast(long) b1 == 0x01_02_03_04_05_06L);
179         auto b2 = BigInt(true, magnitude);
180         assert(cast(long) b2 == -0x01_02_03_04_05_06L);
181     }
182 
183     /// Construct a `BigInt` from a built-in integral type.
184     this(T)(T x) pure nothrow @safe
185     if (isIntegral!T)
186     {
187         data = data.init; // @@@: Workaround for compiler bug
188         opAssign(x);
189     }
190 
191     ///
192     @safe unittest
193     {
194         ulong data = 1_000_000_000_000;
195         auto bigData = BigInt(data);
196         assert(bigData == BigInt("1_000_000_000_000"));
197     }
198 
199     /// Construct a `BigInt` from another `BigInt`.
200     this(T)(T x) pure nothrow @safe
201     if (is(immutable T == immutable BigInt))
202     {
203         opAssign(x);
204     }
205 
206     ///
207     @safe unittest
208     {
209         const(BigInt) b1 = BigInt("1_234_567_890");
210         BigInt b2 = BigInt(b1);
211         assert(b2 == BigInt("1_234_567_890"));
212     }
213 
214     /// Assignment from built-in integer types.
215     BigInt opAssign(T)(T x) pure nothrow @safe
216     if (isIntegral!T)
217     {
218         data = cast(ulong) absUnsign(x);
219         sign = (x < 0);
220         return this;
221     }
222 
223     ///
224     @safe unittest
225     {
226         auto b = BigInt("123");
227         b = 456;
228         assert(b == BigInt("456"));
229     }
230 
231     /// Assignment from another BigInt.
232     BigInt opAssign(T:BigInt)(T x) pure @nogc @safe
233     {
234         data = x.data;
235         sign = x.sign;
236         return this;
237     }
238 
239     ///
240     @safe unittest
241     {
242         auto b1 = BigInt("123");
243         auto b2 = BigInt("456");
244         b2 = b1;
245         assert(b2 == BigInt("123"));
246     }
247 
248     /**
249      * Implements assignment operators from built-in integers of the form
250      * `BigInt op= integer`.
251      */
252     BigInt opOpAssign(string op, T)(T y) pure nothrow @safe return scope
253     if ((op=="+" || op=="-" || op=="*" || op=="/" || op=="%"
254         || op==">>" || op=="<<" || op=="^^" || op=="|" || op=="&" || op=="^") && isIntegral!T)
255     {
256         ulong u = absUnsign(y);
257 
258         static if (op=="+")
259         {
260             data = BigUint.addOrSubInt!ulong(data, u, wantSub: sign != (y<0), sign);
261         }
262         else static if (op=="-")
263         {
264             data = BigUint.addOrSubInt!ulong(data, u, wantSub: sign == (y<0), sign);
265         }
266         else static if (op=="*")
267         {
268             if (y == 0 || data.isZero())
269             {
270                 sign = false;
271                 data = 0UL;
272                 return this;
273             }
274             else
275             {
276                 sign = ( sign != (y<0) );
277                 data = BigUint.mulInt(data, u);
278             }
279         }
280         else static if (op=="/")
281         {
282             assert(y != 0, "Division by zero");
283             static if (T.sizeof <= uint.sizeof)
284             {
285                 data = BigUint.divInt(data, cast(uint) u);
286             }
287             else
288             {
289                 data = BigUint.divInt(data, u);
290             }
291             sign = data.isZero() ? false : sign ^ (y < 0);
292         }
293         else static if (op=="%")
294         {
295             assert(y != 0, "Division by zero");
296             static if (is(immutable(T) == immutable(long)) || is( immutable(T) == immutable(ulong) ))
297             {
298                 this %= BigInt(y);
299             }
300             else
301             {
302                 data = cast(ulong) BigUint.modInt(data, cast(uint) u);
303                 if (data.isZero())
304                     sign = false;
305             }
306             // x%y always has the same sign as x.
307             // This is not the same as mathematical mod.
308         }
309         else static if (op==">>" || op=="<<")
310         {
311             // Do a left shift if y>0 and <<, or
312             // if y<0 and >>; else do a right shift.
313             if (y == 0)
314                 return this;
315             else if ((y > 0) == (op=="<<"))
316             {
317                 // Sign never changes during left shift
318                 data = data.opBinary!(op)(u);
319             }
320             else
321             {
322                 data = data.opBinary!(op)(u);
323                 if (data.isZero())
324                     sign = false;
325             }
326         }
327         else static if (op=="^^")
328         {
329             sign = (y & 1) ? sign : false;
330             if (y < 0)
331             {
332                 checkDivByZero();
333                 data = cast(ulong) (data == 1);
334             }
335             else
336             {
337                 data = BigUint.pow(data, u);
338             }
339         }
340         else static if (op=="&")
341         {
342             if (y >= 0 && (y <= 1 || !sign)) // In these cases we can avoid some allocation.
343             {
344                 static if (T.sizeof <= uint.sizeof && BigDigit.sizeof <= uint.sizeof)
345                     data = cast(ulong) data.peekUint(0) & y;
346                 else
347                     data = data.peekUlong(0) & y;
348                 sign = false;
349             }
350             else
351             {
352                 BigInt b = y;
353                 opOpAssign!op(b);
354             }
355         }
356         else static if (op=="|" || op=="^")
357         {
358             BigInt b = y;
359             opOpAssign!op(b);
360         }
361         else static assert(0, "BigInt " ~ op[0..$-1] ~ "= " ~ T.stringof ~ " is not supported");
362         return this;
363     }
364 
365     // https://issues.dlang.org/show_bug.cgi?id=10565
366 @safe unittest
367 {
368     // Test cases from the issue
369     BigInt a = BigInt("0");
370     BigInt b = BigInt("-0");
371     BigInt c = BigInt("0") * -1;
372     BigInt d = BigInt("0") * -42;
373     BigInt e = BigInt("0"); e *= -1;
374     BigInt f = BigInt(c);
375     BigInt g = BigInt("0") * cast(byte) -1;
376     BigInt h = BigInt("0"); h *= BigInt("-1");
377     BigInt i = BigInt("0"); i -= 2 * i;
378     BigInt j = BigInt("0"); j = -j;
379     // All of these should be zero and not negative
380     auto values = [a, b, c, d, e, f, g, h, i, j];
381     foreach (val; values)
382     {
383         assert(val == 0, "BigInt value should be equal to zero");
384         assert(!(val < 0), "BigInt zero should not be negative");
385     }
386 }
387 
388     ///
389     @safe unittest
390     {
391         auto b = BigInt("1_000_000_000");
392 
393         b += 12345;
394         assert(b == BigInt("1_000_012_345"));
395 
396         b /= 5;
397         assert(b == BigInt("200_002_469"));
398     }
399 
400     // https://issues.dlang.org/show_bug.cgi?id=16264
401     @safe unittest
402     {
403         auto a = BigInt(
404     `335690982744637013564796917901053301979460129353374296317539383938630086938` ~
405     `465898213033510992292836631752875403891802201862860531801760096359705447768` ~
406     `957432600293361240407059207520920532482429912948952142341440301429494694368` ~
407     `264560802292927144211230021750155988283029753927847924288850436812178022006` ~
408     `408597793414273953252832688620479083497367463977081627995406363446761896298` ~
409     `967177607401918269561385622811274398143647535024987050366350585544531063531` ~
410     `7118554808325723941557169427279911052268935775`);
411 
412         auto b = BigInt(
413     `207672245542926038535480439528441949928508406405023044025560363701392340829` ~
414     `852529131306106648201340460604257466180580583656068555417076345439694125326` ~
415     `843947164365500055567495554645796102453565953360564114634705366335703491527` ~
416     `429426780005741168078089657359833601261803592920462081364401456331489106355` ~
417     `199133982282631108670436696758342051198891939367812305559960349479160308314` ~
418     `068518200681530999860641597181672463704794566473241690395901768680673716414` ~
419     `243691584391572899147223065906633310537507956952626106509069491302359792769` ~
420     `378934570685117202046921464019396759638376362935855896435623442486036961070` ~
421     `534574698959398017332214518246531363445309522357827985468581166065335726996` ~
422     `711467464306784543112544076165391268106101754253962102479935962248302404638` ~
423     `21737237102628470475027851189594709504`);
424 
425         BigInt c = a * b;  // Crashes
426 
427         assert(c == BigInt(
428     `697137001950904057507249234183127244116872349433141878383548259425589716813` ~
429     `135440660252012378417669596912108637127036044977634382385990472429604619344` ~
430     `738746224291111527200379708978133071390303850450970292020176369525401803474` ~
431     `998613408923490273129022167907826017408385746675184651576154302536663744109` ~
432     `111018961065316024005076097634601030334948684412785487182572502394847587887` ~
433     `507385831062796361152176364659197432600147716058873232435238712648552844428` ~
434     `058885217631715287816333209463171932255049134340904981280717725999710525214` ~
435     `161541960645335744430049558161514565159449390036287489478108344584188898872` ~
436     `434914159748515512161981956372737022393466624249130107254611846175580584736` ~
437     `276213025837422102290580044755202968610542057651282410252208599309841499843` ~
438     `672251048622223867183370008181364966502137725166782667358559333222947265344` ~
439     `524195551978394625568228658697170315141077913403482061673401937141405425042` ~
440     `283546509102861986303306729882186190883772633960389974665467972016939172303` ~
441     `653623175801495207204880400522581834672918935651426160175413277309985678579` ~
442     `830872397214091472424064274864210953551447463312267310436493480881235642109` ~
443     `668498742629676513172286703948381906930297135997498416573231570483993847269` ~
444     `479552708416124555462530834668011570929850407031109157206202741051573633443` ~
445     `58105600`
446         ));
447     }
448 
449     // https://issues.dlang.org/show_bug.cgi?id=24028
450     @system unittest
451     {
452         import std.exception : assertThrown;
453         import core.exception : AssertError;
454 
455         assert(BigInt(100) ^^ -1 == BigInt(0));
456         assert(BigInt(1) ^^ -1 == BigInt(1));
457         assert(BigInt(-1) ^^ -1 == BigInt(-1));
458         assert(BigInt(-1) ^^ -2 == BigInt(1));
459         assertThrown!AssertError(BigInt(0) ^^ -1);
460     }
461 
462     /**
463      * Implements assignment operators of the form `BigInt op= BigInt`.
464      */
465     BigInt opOpAssign(string op, T)(T y) pure nothrow @safe return scope
466     if ((op=="+" || op== "-" || op=="*" || op=="|" || op=="&" || op=="^" || op=="/" || op=="%") && is (T: BigInt))
467     {
468         static if (op == "+")
469         {
470             data = BigUint.addOrSub(data, y.data, sign != y.sign, sign);
471         }
472         else static if (op == "-")
473         {
474             data = BigUint.addOrSub(data, y.data, sign == y.sign, sign);
475         }
476         else static if (op == "*")
477         {
478             data = BigUint.mul(data, y.data);
479             sign = isZero() ? false : sign ^ y.sign;
480         }
481         else static if (op == "/")
482         {
483             y.checkDivByZero();
484             if (!isZero())
485             {
486                 data = BigUint.div(data, y.data);
487                 sign = isZero() ? false : sign ^ y.sign;
488             }
489         }
490         else static if (op == "%")
491         {
492             y.checkDivByZero();
493             if (!isZero())
494             {
495                 data = BigUint.mod(data, y.data);
496                 // x%y always has the same sign as x.
497                 if (isZero())
498                     sign = false;
499             }
500         }
501         else static if (op == "|" || op == "&" || op == "^")
502         {
503             data = BigUint.bitwiseOp!op(data, y.data, sign, y.sign, sign);
504         }
505         else static assert(0, "BigInt " ~ op[0..$-1] ~ "= " ~
506             T.stringof ~ " is not supported");
507         return this;
508     }
509 
510     ///
511     @safe unittest
512     {
513         auto x = BigInt("123");
514         auto y = BigInt("321");
515         x += y;
516         assert(x == BigInt("444"));
517     }
518 
519     /**
520      * Implements binary operators between `BigInt`s.
521      */
522     BigInt opBinary(string op, T)(T y) pure nothrow @safe const return scope
523     if ((op=="+" || op == "*" || op=="-" || op=="|" || op=="&" || op=="^" ||
524         op=="/" || op=="%") && is (T: BigInt))
525     {
526         BigInt r = this;
527         return r.opOpAssign!(op)(y);
528     }
529 
530     ///
531     @safe unittest
532     {
533         auto x = BigInt("123");
534         auto y = BigInt("456");
535         BigInt z = x * y;
536         assert(z == BigInt("56088"));
537     }
538 
539     /**
540      * Implements binary operators between `BigInt`'s and built-in integers.
541      */
542     BigInt opBinary(string op, T)(T y) pure nothrow @safe const return scope
543     if ((op=="+" || op == "*" || op=="-" || op=="/" || op=="|" || op=="&" ||
544         op=="^"|| op==">>" || op=="<<" || op=="^^")
545         && isIntegral!T)
546     {
547         BigInt r = this;
548         r.opOpAssign!(op)(y);
549         return r;
550     }
551 
552     ///
553     @safe unittest
554     {
555         auto x = BigInt("123");
556         x *= 300;
557         assert(x == BigInt("36900"));
558     }
559 
560     /**
561         Implements a narrowing remainder operation with built-in integer types.
562 
563         This binary operator returns a narrower, built-in integer type
564         where applicable, according to the following table.
565 
566         $(TABLE ,
567         $(TR $(TD `BigInt`) $(TD $(CODE_PERCENT)) $(TD `uint`) $(TD $(RARR)) $(TD `long`))
568         $(TR $(TD `BigInt`) $(TD $(CODE_PERCENT)) $(TD `long`) $(TD $(RARR)) $(TD `long`))
569         $(TR $(TD `BigInt`) $(TD $(CODE_PERCENT)) $(TD `ulong`) $(TD $(RARR)) $(TD `BigInt`))
570         $(TR $(TD `BigInt`) $(TD $(CODE_PERCENT)) $(TD other type) $(TD $(RARR)) $(TD `int`))
571         )
572      */
573     auto opBinary(string op, T)(T y) pure nothrow @safe const
574     if (op == "%" && isIntegral!T)
575     {
576         assert(y != 0, "% 0 not allowed");
577 
578         // BigInt % uint => long
579         // BigInt % long => long
580         // BigInt % ulong => BigInt
581         // BigInt % other_type => int
582         static if (is(immutable T == immutable long) || is(immutable T == immutable ulong))
583         {
584             auto r = this % BigInt(y);
585 
586             static if (is(immutable T == immutable long))
587             {
588                 return r.toLong();
589             }
590             else
591             {
592                 // return as-is to avoid overflow
593                 return r;
594             }
595         }
596         else
597         {
598             immutable uint u = absUnsign(y);
599             static if (is(immutable T == immutable uint))
600                alias R = long;
601             else
602                alias R = int;
603             R rem = BigUint.modInt(data, u);
604             // x%y always has the same sign as x.
605             // This is not the same as mathematical mod.
606             return sign ? -rem : rem;
607         }
608     }
609 
610     ///
611     @safe unittest
612     {
613         auto  x  = BigInt("1_000_000_500");
614         long  l  = 1_000_000L;
615         ulong ul = 2_000_000UL;
616         int   i  = 500_000;
617         short s  = 30_000;
618 
619         assert(is(typeof(x % l)  == long)   && x % l  == 500L);
620         assert(is(typeof(x % ul) == BigInt) && x % ul == BigInt(500));
621         assert(is(typeof(x % i)  == int)    && x % i  == 500);
622         assert(is(typeof(x % s)  == int)    && x % s  == 10500);
623     }
624 
625     /**
626         Implements operators with built-in integers on the left-hand side and
627         `BigInt` on the right-hand side.
628      */
629     BigInt opBinaryRight(string op, T)(T y) pure nothrow @safe const
630     if ((op=="+" || op=="*" || op=="|" || op=="&" || op=="^") && isIntegral!T)
631     {
632         return opBinary!(op)(y);
633     }
634 
635     ///
636     @safe unittest
637     {
638         auto x = BigInt("100");
639         BigInt y = 123 + x;
640         assert(y == BigInt("223"));
641 
642         BigInt z = 123 - x;
643         assert(z == BigInt("23"));
644 
645         // Dividing a built-in integer type by BigInt always results in
646         // something that fits in a built-in type, so the built-in type is
647         // returned, not BigInt.
648         assert(is(typeof(1000 / x) == int));
649         assert(1000 / x == 10);
650     }
651 
652     //  BigInt = integer op BigInt
653     /// ditto
654     BigInt opBinaryRight(string op, T)(T y) pure nothrow @safe const
655     if (op == "-" && isIntegral!T)
656     {
657         ulong u = absUnsign(y);
658         BigInt r;
659         static if (op == "-")
660         {
661             r.sign = sign;
662             r.data = BigUint.addOrSubInt!ulong(data, u, wantSub: sign == (y<0), r.sign);
663             r.negate();
664         }
665         return r;
666     }
667 
668     //  integer = integer op BigInt
669     /// ditto
670     T opBinaryRight(string op, T)(T x) pure nothrow @safe const
671     if ((op=="%" || op=="/") && isIntegral!T)
672     {
673         checkDivByZero();
674 
675         static if (op == "%")
676         {
677             // x%y always has the same sign as x.
678             if (data.ulongLength > 1)
679                 return x;
680             immutable u = absUnsign(x);
681             immutable rem = u % data.peekUlong(0);
682             // x%y always has the same sign as x.
683             return cast(T)((x<0) ? -rem : rem);
684         }
685         else static if (op == "/")
686         {
687             if (data.ulongLength > 1)
688                 return 0;
689             return cast(T)(x / data.peekUlong(0));
690         }
691     }
692 
693     // const unary operations
694     /**
695         Implements `BigInt` unary operators.
696      */
697     BigInt opUnary(string op)() pure nothrow @safe const
698     if (op=="+" || op=="-" || op=="~")
699     {
700        static if (op=="-")
701        {
702             BigInt r = this;
703             r.negate();
704             return r;
705         }
706         else static if (op=="~")
707         {
708             return -(this+1);
709         }
710         else static if (op=="+")
711            return this;
712     }
713 
714     // non-const unary operations
715     /// ditto
716     BigInt opUnary(string op)() pure nothrow @safe
717     if (op=="++" || op=="--")
718     {
719         static if (op=="++")
720         {
721             data = BigUint.addOrSubInt!ulong(data, 1UL, wantSub: sign, sign);
722             return this;
723         }
724         else static if (op=="--")
725         {
726             data = BigUint.addOrSubInt!ulong(data, 1UL, wantSub: !sign, sign);
727             return this;
728         }
729     }
730 
731     ///
732     @safe unittest
733     {
734         auto x = BigInt("1234");
735         assert(-x == BigInt("-1234"));
736 
737         ++x;
738         assert(x == BigInt("1235"));
739     }
740 
741     /**
742         Implements `BigInt` equality test with other `BigInt`'s and built-in
743         numeric types.
744      */
745     bool opEquals()(auto ref const BigInt y) const pure @nogc @safe
746     {
747        return sign == y.sign && y.data == data;
748     }
749 
750     /// ditto
751     bool opEquals(T)(const T y) const pure nothrow @nogc @safe
752     if (isIntegral!T)
753     {
754         if (sign != (y<0))
755             return 0;
756         return data.opEquals(cast(ulong) absUnsign(y));
757     }
758 
759     /// ditto
760     bool opEquals(T)(const T y) const pure nothrow @nogc
761     if (isFloatingPoint!T)
762     {
763         return 0 == opCmp(y);
764     }
765 
766     ///
767     @safe unittest
768     {
769         // Note that when comparing a BigInt to a float or double the
770         // full precision of the BigInt is always considered, unlike
771         // when comparing an int to a float or a long to a double.
772         assert(BigInt(123456789) != cast(float) 123456789);
773     }
774 
775     @safe unittest
776     {
777         auto x = BigInt("12345");
778         auto y = BigInt("12340");
779         int z = 12345;
780         int w = 54321;
781 
782         assert(x == x);
783         assert(x != y);
784         assert(x == y + 5);
785         assert(x == z);
786         assert(x != w);
787     }
788 
789     @safe unittest
790     {
791         import std.math.operations : nextDown, nextUp;
792 
793         const x = BigInt("0x1abc_de80_0000_0000_0000_0000_0000_0000");
794         BigInt x1 = x + 1;
795         BigInt x2 = x - 1;
796 
797         const d = 0x1.abcde8p124;
798         assert(x == d);
799         assert(x1 != d);
800         assert(x2 != d);
801         assert(x != nextUp(d));
802         assert(x != nextDown(d));
803         assert(x != double.nan);
804 
805         const dL = 0x1.abcde8p124L;
806         assert(x == dL);
807         assert(x1 != dL);
808         assert(x2 != dL);
809         assert(x != nextUp(dL));
810         assert(x != nextDown(dL));
811         assert(x != real.nan);
812 
813         assert(BigInt(0) == 0.0f);
814         assert(BigInt(0) == 0.0);
815         assert(BigInt(0) == 0.0L);
816         assert(BigInt(0) == -0.0f);
817         assert(BigInt(0) == -0.0);
818         assert(BigInt(0) == -0.0L);
819         assert(BigInt("999_999_999_999_999_999_999_999_999_999_999_999_999") != float.infinity);
820     }
821 
822     /**
823         Implements casting to `bool`.
824      */
825     T opCast(T:bool)() pure nothrow @nogc @safe const
826     {
827         return !isZero();
828     }
829 
830     ///
831     @safe unittest
832     {
833         // Non-zero values are regarded as true
834         auto x = BigInt("1");
835         auto y = BigInt("10");
836         assert(x);
837         assert(y);
838 
839         // Zero value is regarded as false
840         auto z = BigInt("0");
841         assert(!z);
842     }
843 
844     /**
845         Implements casting to integer types.
846 
847         Throws: $(REF ConvOverflowException, std,conv) if the number exceeds
848         the target type's range.
849      */
850     T opCast(T:ulong)() pure @safe const
851     {
852         if (isUnsigned!T && sign)
853             { /* throw */ }
854         else
855         if (data.ulongLength == 1)
856         {
857             ulong l = data.peekUlong(0);
858             if (isUnsigned!T || !sign)
859             {
860                 if (l <= T.max)
861                     return cast(T) l;
862             }
863             else
864             {
865                 if (l <= ulong(T.max)+1)
866                     return cast(T)-long(l); // -long.min == long.min
867             }
868         }
869 
870         import std.conv : ConvOverflowException;
871         import std.string : format;
872         throw new ConvOverflowException(
873             "BigInt(%s) cannot be represented as a %s"
874             .format(this.toDecimalString, T.stringof));
875     }
876 
877     ///
878     @safe unittest
879     {
880         import std.conv : to, ConvOverflowException;
881         import std.exception : assertThrown;
882 
883         assert(BigInt("0").to!int == 0);
884 
885         assert(BigInt("0").to!ubyte == 0);
886         assert(BigInt("255").to!ubyte == 255);
887         assertThrown!ConvOverflowException(BigInt("256").to!ubyte);
888         assertThrown!ConvOverflowException(BigInt("-1").to!ubyte);
889     }
890 
891     @safe unittest
892     {
893         import std.conv : to, ConvOverflowException;
894         import std.exception : assertThrown;
895 
896         assert(BigInt("-1").to!byte == -1);
897         assert(BigInt("-128").to!byte == -128);
898         assert(BigInt("127").to!byte == 127);
899         assertThrown!ConvOverflowException(BigInt("-129").to!byte);
900         assertThrown!ConvOverflowException(BigInt("128").to!byte);
901 
902         assert(BigInt("0").to!uint == 0);
903         assert(BigInt("4294967295").to!uint == uint.max);
904         assertThrown!ConvOverflowException(BigInt("4294967296").to!uint);
905         assertThrown!ConvOverflowException(BigInt("-1").to!uint);
906 
907         assert(BigInt("-1").to!int == -1);
908         assert(BigInt("-2147483648").to!int == int.min);
909         assert(BigInt("2147483647").to!int == int.max);
910         assertThrown!ConvOverflowException(BigInt("-2147483649").to!int);
911         assertThrown!ConvOverflowException(BigInt("2147483648").to!int);
912 
913         assert(BigInt("0").to!ulong == 0);
914         assert(BigInt("18446744073709551615").to!ulong == ulong.max);
915         assertThrown!ConvOverflowException(BigInt("18446744073709551616").to!ulong);
916         assertThrown!ConvOverflowException(BigInt("-1").to!ulong);
917 
918         assert(BigInt("-1").to!long == -1);
919         assert(BigInt("-9223372036854775808").to!long == long.min);
920         assert(BigInt("9223372036854775807").to!long == long.max);
921         assertThrown!ConvOverflowException(BigInt("-9223372036854775809").to!long);
922         assertThrown!ConvOverflowException(BigInt("9223372036854775808").to!long);
923     }
924 
925     /**
926         Implements casting to floating point types.
927      */
928     T opCast(T)() @safe nothrow @nogc const
929     if (isFloatingPoint!T)
930     {
931         return toFloat!(T, "nearest");
932     }
933 
934     ///
935     @system unittest
936     {
937         assert(cast(float)  BigInt("35540592535949172786332045140593475584")
938                 == 35540592535949172786332045140593475584.0f);
939         assert(cast(double) BigInt("35540601499647381470685035515422441472")
940                 == 35540601499647381470685035515422441472.0);
941         assert(cast(real)   BigInt("35540601499647381470685035515422441472")
942                 == 35540601499647381470685035515422441472.0L);
943 
944         assert(cast(float)  BigInt("-0x1345_6780_0000_0000_0000_0000_0000") == -0x1.3456_78p+108f       );
945         assert(cast(double) BigInt("-0x1345_678a_bcde_f000_0000_0000_0000") == -0x1.3456_78ab_cdefp+108 );
946         assert(cast(real)   BigInt("-0x1345_678a_bcde_f000_0000_0000_0000") == -0x1.3456_78ab_cdefp+108L);
947     }
948 
949     /// Rounding when casting to floating point
950     @system unittest
951     {
952         // BigInts whose values cannot be exactly represented as float/double/real
953         // are rounded when cast to float/double/real. When cast to float or
954         // double or 64-bit real the rounding is strictly defined. When cast
955         // to extended-precision real the rounding rules vary by environment.
956 
957         // BigInts that fall somewhere between two non-infinite floats/doubles
958         // are rounded to the closer value when cast to float/double.
959         assert(cast(float) BigInt(0x1aaa_aae7) == 0x1.aaa_aaep+28f);
960         assert(cast(float) BigInt(0x1aaa_aaff) == 0x1.aaa_ab0p+28f);
961         assert(cast(float) BigInt(-0x1aaa_aae7) == -0x1.aaaaaep+28f);
962         assert(cast(float) BigInt(-0x1aaa_aaff) == -0x1.aaaab0p+28f);
963 
964         assert(cast(double) BigInt(0x1aaa_aaaa_aaaa_aa77) == 0x1.aaa_aaaa_aaaa_aa00p+60);
965         assert(cast(double) BigInt(0x1aaa_aaaa_aaaa_aaff) == 0x1.aaa_aaaa_aaaa_ab00p+60);
966         assert(cast(double) BigInt(-0x1aaa_aaaa_aaaa_aa77) == -0x1.aaa_aaaa_aaaa_aa00p+60);
967         assert(cast(double) BigInt(-0x1aaa_aaaa_aaaa_aaff) == -0x1.aaa_aaaa_aaaa_ab00p+60);
968 
969         // BigInts that fall exactly between two non-infinite floats/doubles
970         // are rounded away from zero when cast to float/double. (Note that
971         // in most environments this is NOT the same rounding rule rule used
972         // when casting int/long to float/double.)
973         assert(cast(float) BigInt(0x1aaa_aaf0) == 0x1.aaa_ab0p+28f);
974         assert(cast(float) BigInt(-0x1aaa_aaf0) == -0x1.aaaab0p+28f);
975 
976         assert(cast(double) BigInt(0x1aaa_aaaa_aaaa_aa80) == 0x1.aaa_aaaa_aaaa_ab00p+60);
977         assert(cast(double) BigInt(-0x1aaa_aaaa_aaaa_aa80) == -0x1.aaa_aaaa_aaaa_ab00p+60);
978 
979         // BigInts that are bounded on one side by the largest positive or
980         // most negative finite float/double and on the other side by infinity
981         // or -infinity are rounded as if in place of infinity was the value
982         // `2^^(T.max_exp)` when cast to float/double.
983         assert(cast(float) BigInt("999_999_999_999_999_999_999_999_999_999_999_999_999") == float.infinity);
984         assert(cast(float) BigInt("-999_999_999_999_999_999_999_999_999_999_999_999_999") == -float.infinity);
985 
986         assert(cast(double) BigInt("999_999_999_999_999_999_999_999_999_999_999_999_999") < double.infinity);
987         assert(cast(real) BigInt("999_999_999_999_999_999_999_999_999_999_999_999_999") < real.infinity);
988     }
989 
990     @safe unittest
991     {
992         // Test exponent overflow is correct.
993         assert(cast(float) BigInt(0x1fffffff) == 0x1.000000p+29f);
994         assert(cast(double) BigInt(0x1fff_ffff_ffff_fff0) == 0x1.000000p+61);
995     }
996 
997     private T toFloat(T, string roundingMode)() @safe nothrow @nogc const
998     if (__traits(isFloating, T) && (roundingMode == "nearest" || roundingMode == "truncate"))
999     {
1000         import core.bitop : bsr;
1001         enum performRounding = (roundingMode == "nearest");
1002         enum performTruncation = (roundingMode == "truncate");
1003         static assert(performRounding || performTruncation, "unrecognized rounding mode");
1004         enum int totalNeededBits = T.mant_dig + int(performRounding);
1005         static if (totalNeededBits <= 64)
1006         {
1007             // We need to examine the top two 64-bit words, not just the top one,
1008             // since the top word could have just a single significant bit.
1009             const ulongLength = data.ulongLength;
1010             const ulong w1 = data.peekUlong(ulongLength - 1);
1011             if (w1 == 0)
1012                 return T(0); // Special: exponent should be all zero bits, plus bsr(w1) is undefined.
1013             const ulong w2 = ulongLength < 2 ? 0 : data.peekUlong(ulongLength - 2);
1014             const uint w1BitCount = bsr(w1) + 1;
1015             ulong sansExponent = (w1 << (64 - w1BitCount)) | (w2 >>> (w1BitCount));
1016             size_t exponent = (ulongLength - 1) * 64 + w1BitCount + 1;
1017             static if (performRounding)
1018             {
1019                 sansExponent += 1UL << (64 - totalNeededBits);
1020                 if (0 <= cast(long) sansExponent) // Use high bit to detect overflow.
1021                 {
1022                     // Do not bother filling in the high bit of sansExponent
1023                     // with 1. It will be discarded by float and double and 80
1024                     // bit real cannot be on this path with rounding enabled.
1025                     exponent += 1;
1026                 }
1027             }
1028             static if (T.mant_dig == float.mant_dig)
1029             {
1030                 if (exponent >= T.max_exp)
1031                     return isNegative ? -T.infinity : T.infinity;
1032                 uint resultBits = (uint(isNegative) << 31) | // sign bit
1033                     ((0xFF & (exponent - float.min_exp)) << 23) | // exponent
1034                     cast(uint) ((sansExponent << 1) >>> (64 - 23)); // mantissa.
1035                 // TODO: remove @trusted lambda after DIP 1000 is enabled by default.
1036                 return (() @trusted => *cast(float*) &resultBits)();
1037             }
1038             else static if (T.mant_dig == double.mant_dig)
1039             {
1040                 if (exponent >= T.max_exp)
1041                     return isNegative ? -T.infinity : T.infinity;
1042                 ulong resultBits = (ulong(isNegative) << 63) | // sign bit
1043                     ((0x7FFUL & (exponent - double.min_exp)) << 52) | // exponent
1044                     ((sansExponent << 1) >>> (64 - 52)); // mantissa.
1045                 // TODO: remove @trusted lambda after DIP 1000 is enabled by default.
1046                 return (() @trusted => *cast(double*) &resultBits)();
1047             }
1048             else
1049             {
1050                 import core.math : ldexp;
1051                 return ldexp(isNegative ? -cast(real) sansExponent : cast(real) sansExponent,
1052                     cast(int) exponent - 65);
1053             }
1054         }
1055         else
1056         {
1057             import core.math : ldexp;
1058             const ulongLength = data.ulongLength;
1059             if ((ulongLength - 1) * 64L > int.max)
1060                 return isNegative ? -T.infinity : T.infinity;
1061             int scale = cast(int) ((ulongLength - 1) * 64);
1062             const ulong w1 = data.peekUlong(ulongLength - 1);
1063             if (w1 == 0)
1064                 return T(0); // Special: bsr(w1) is undefined.
1065             int bitsStillNeeded = totalNeededBits - bsr(w1) - 1;
1066             T acc = ldexp(cast(T) w1, scale);
1067             for (ptrdiff_t i = ulongLength - 2; i >= 0 && bitsStillNeeded > 0; i--)
1068             {
1069                 ulong w = data.peekUlong(i);
1070                 // To round towards zero we must make sure not to use too many bits.
1071                 if (bitsStillNeeded >= 64)
1072                 {
1073                     acc += ldexp(cast(T) w, scale -= 64);
1074                     bitsStillNeeded -= 64;
1075                 }
1076                 else
1077                 {
1078                     w = (w >>> (64 - bitsStillNeeded)) << (64 - bitsStillNeeded);
1079                     acc += ldexp(cast(T) w, scale -= 64);
1080                     break;
1081                 }
1082             }
1083             if (isNegative)
1084                 acc = -acc;
1085             return cast(T) acc;
1086         }
1087     }
1088 
1089     /**
1090         Implements casting to/from qualified `BigInt`'s.
1091 
1092         Warning: Casting to/from `const` or `immutable` may break type
1093         system guarantees. Use with care.
1094      */
1095     T opCast(T)() pure nothrow @nogc const
1096     if (is(immutable T == immutable BigInt))
1097     {
1098         return this;
1099     }
1100 
1101     ///
1102     @safe unittest
1103     {
1104         const(BigInt) x = BigInt("123");
1105         BigInt y = cast() x;    // cast away const
1106         assert(y == x);
1107     }
1108 
1109     // Hack to make BigInt's typeinfo.compare work properly.
1110     // Note that this must appear before the other opCmp overloads, otherwise
1111     // DMD won't find it.
1112     /**
1113         Implements 3-way comparisons of `BigInt` with `BigInt` or `BigInt` with
1114         built-in numeric types.
1115      */
1116     int opCmp(ref const BigInt y) pure nothrow @nogc @safe const
1117     {
1118         // Simply redirect to the "real" opCmp implementation.
1119         return this.opCmp!BigInt(y);
1120     }
1121 
1122     /// ditto
1123     int opCmp(T)(const T y) pure nothrow @nogc @safe const
1124     if (isIntegral!T)
1125     {
1126         if (sign != (y<0) )
1127             return sign ? -1 : 1;
1128         int cmp = data.opCmp(cast(ulong) absUnsign(y));
1129         return sign? -cmp: cmp;
1130     }
1131     /// ditto
1132     int opCmp(T)(const T y) nothrow @nogc @safe const
1133     if (isFloatingPoint!T)
1134     {
1135         import core.bitop : bsr;
1136         import std.math.operations : cmp;
1137         import std.math.traits : isFinite;
1138 
1139         const asFloat = toFloat!(T, "truncate");
1140         if (asFloat != y)
1141             return cmp(asFloat, y); // handles +/- NaN.
1142         if (!isFinite(y))
1143             return isNegative ? 1 : -1;
1144         const ulongLength = data.ulongLength;
1145         const w1 = data.peekUlong(ulongLength - 1);
1146         if (w1 == 0)
1147             return 0; // Special: bsr(w1) is undefined.
1148         const numSignificantBits = (ulongLength - 1) * 64 + bsr(w1) + 1;
1149         for (ptrdiff_t bitsRemainingToCheck = numSignificantBits - T.mant_dig, i = 0;
1150             bitsRemainingToCheck > 0; i++, bitsRemainingToCheck -= 64)
1151         {
1152             auto word = data.peekUlong(i);
1153             if (word == 0)
1154                 continue;
1155             // Make sure we're only checking digits that are beyond
1156             // the precision of `y`.
1157             if (bitsRemainingToCheck < 64 && (word << (64 - bitsRemainingToCheck)) == 0)
1158                 break; // This can only happen on the last loop iteration.
1159             return isNegative ? -1 : 1;
1160         }
1161         return 0;
1162     }
1163     /// ditto
1164     int opCmp(T:BigInt)(const T y) pure nothrow @nogc @safe const
1165     {
1166         if (sign != y.sign)
1167             return sign ? -1 : 1;
1168         immutable cmp = data.opCmp(y.data);
1169         return sign? -cmp: cmp;
1170     }
1171 
1172     ///
1173     @safe unittest
1174     {
1175         auto x = BigInt("100");
1176         auto y = BigInt("10");
1177         int z = 50;
1178         const int w = 200;
1179 
1180         assert(y < x);
1181         assert(x > z);
1182         assert(z > y);
1183         assert(x < w);
1184     }
1185 
1186     ///
1187     @safe unittest
1188     {
1189         auto x = BigInt("0x1abc_de80_0000_0000_0000_0000_0000_0000");
1190         BigInt y = x - 1;
1191         BigInt z = x + 1;
1192 
1193         double d = 0x1.abcde8p124;
1194         assert(y < d);
1195         assert(z > d);
1196         assert(x >= d && x <= d);
1197 
1198         // Note that when comparing a BigInt to a float or double the
1199         // full precision of the BigInt is always considered, unlike
1200         // when comparing an int to a float or a long to a double.
1201         assert(BigInt(123456789) < cast(float) 123456789);
1202     }
1203 
1204     @safe unittest
1205     {
1206         assert(BigInt("999_999_999_999_999_999_999_999_999_999_999_999_999") < float.infinity);
1207 
1208         // Test `real` works.
1209         auto x = BigInt("0x1abc_de80_0000_0000_0000_0000_0000_0000");
1210         BigInt y = x - 1;
1211         BigInt z = x + 1;
1212 
1213         real d = 0x1.abcde8p124;
1214         assert(y < d);
1215         assert(z > d);
1216         assert(x >= d && x <= d);
1217 
1218         // Test comparison for numbers of 64 bits or fewer.
1219         auto w1 = BigInt(0x1abc_de80_0000_0000);
1220         auto w2 = w1 - 1;
1221         auto w3 = w1 + 1;
1222         assert(w1.ulongLength == 1);
1223         assert(w2.ulongLength == 1);
1224         assert(w3.ulongLength == 1);
1225 
1226         double e = 0x1.abcde8p+60;
1227         assert(w1 >= e && w1 <= e);
1228         assert(w2 < e);
1229         assert(w3 > e);
1230 
1231         real eL = 0x1.abcde8p+60;
1232         assert(w1 >= eL && w1 <= eL);
1233         assert(w2 < eL);
1234         assert(w3 > eL);
1235     }
1236 
1237     /**
1238         Returns: The value of this `BigInt` as a `long`, or `long.max`/`long.min`
1239         if outside the representable range.
1240      */
1241     long toLong() @safe pure nothrow const @nogc
1242     {
1243         return (sign ? -1 : 1) *
1244           (data.ulongLength == 1  && (data.peekUlong(0) <= sign+cast(ulong)(long.max)) // 1+long.max = |long.min|
1245           ? cast(long)(data.peekUlong(0))
1246           : long.max);
1247     }
1248 
1249     ///
1250     @safe unittest
1251     {
1252         auto b = BigInt("12345");
1253         long l = b.toLong();
1254         assert(l == 12345);
1255     }
1256 
1257     /**
1258         Returns: The value of this `BigInt` as an `int`, or `int.max`/`int.min` if outside
1259         the representable range.
1260      */
1261     int toInt() @safe pure nothrow @nogc const
1262     {
1263         return (sign ? -1 : 1) *
1264           (data.uintLength == 1  && (data.peekUint(0) <= sign+cast(uint)(int.max)) // 1+int.max = |int.min|
1265           ? cast(int)(data.peekUint(0))
1266           : int.max);
1267     }
1268 
1269     ///
1270     @safe unittest
1271     {
1272         auto big = BigInt("5_000_000");
1273         auto i = big.toInt();
1274         assert(i == 5_000_000);
1275 
1276         // Numbers that are too big to fit into an int will be clamped to int.max.
1277         auto tooBig = BigInt("5_000_000_000");
1278         i = tooBig.toInt();
1279         assert(i == int.max);
1280     }
1281 
1282     /// Number of significant `uint`s which are used in storing this number.
1283     /// The absolute value of this `BigInt` is always &lt; 2$(SUPERSCRIPT 32*uintLength)
1284     @property size_t uintLength() @safe pure nothrow @nogc const
1285     {
1286         return data.uintLength;
1287     }
1288 
1289     /// Number of significant `ulong`s which are used in storing this number.
1290     /// The absolute value of this `BigInt` is always &lt; 2$(SUPERSCRIPT 64*ulongLength)
1291     @property size_t ulongLength() @safe pure nothrow @nogc const
1292     {
1293         return data.ulongLength;
1294     }
1295 
1296     /** Convert the `BigInt` to `string`, passing it to the given sink.
1297      *
1298      * Params:
1299      *  sink = An OutputRange for accepting possibly piecewise segments of the
1300      *      formatted string.
1301      *  formatString = A format string specifying the output format.
1302      *
1303      * $(TABLE  Available output formats:,
1304      * $(TR $(TD "d") $(TD  Decimal))
1305      * $(TR $(TD "o") $(TD  Octal))
1306      * $(TR $(TD "x") $(TD  Hexadecimal, lower case))
1307      * $(TR $(TD "X") $(TD  Hexadecimal, upper case))
1308      * $(TR $(TD "s") $(TD  Default formatting (same as "d") ))
1309      * $(TR $(TD null) $(TD Default formatting (same as "d") ))
1310      * )
1311      */
1312     void toString(Writer)(scope ref Writer sink, string formatString) const
1313     {
1314         auto f = FormatSpec!char(formatString);
1315         f.writeUpToNextSpec(sink);
1316         toString!Writer(sink, f);
1317     }
1318 
1319     /// ditto
1320     void toString(Writer)(scope ref Writer sink, scope const ref FormatSpec!char f) const
1321     {
1322         import std.range.primitives : put;
1323         const spec = f.spec;
1324         immutable hex = (spec == 'x' || spec == 'X');
1325         if (!(spec == 's' || spec == 'd' || spec =='o' || hex))
1326             throw new FormatException("Format specifier not understood: %" ~ spec);
1327 
1328         char[] buff;
1329         if (spec == 'X')
1330         {
1331             buff = data.toHexString(0, '_', 0, f.flZero ? '0' : ' ', LetterCase.upper);
1332         }
1333         else if (spec == 'x')
1334         {
1335             buff = data.toHexString(0, '_', 0, f.flZero ? '0' : ' ', LetterCase.lower);
1336         }
1337         else if (spec == 'o')
1338         {
1339             buff = data.toOctalString();
1340         }
1341         else
1342         {
1343             buff = data.toDecimalString(0);
1344         }
1345         assert(buff.length > 0, "Invalid buffer length");
1346 
1347         char signChar = isNegative ? '-' : 0;
1348         auto minw = buff.length + (signChar ? 1 : 0);
1349 
1350         if (!hex && !signChar && (f.width == 0 || minw < f.width))
1351         {
1352             if (f.flPlus)
1353             {
1354                 signChar = '+';
1355                 ++minw;
1356             }
1357             else if (f.flSpace)
1358             {
1359                 signChar = ' ';
1360                 ++minw;
1361             }
1362         }
1363 
1364         immutable maxw = minw < f.width ? f.width : minw;
1365         immutable difw = maxw - minw;
1366 
1367         if (!f.flDash && !f.flZero)
1368             foreach (i; 0 .. difw)
1369                 put(sink, " ");
1370 
1371         if (signChar)
1372         {
1373             scope char[1] buf = signChar;
1374             put(sink, buf[]);
1375         }
1376 
1377         if (!f.flDash && f.flZero)
1378             foreach (i; 0 .. difw)
1379                 put(sink, "0");
1380 
1381         put(sink, buff);
1382 
1383         if (f.flDash)
1384             foreach (i; 0 .. difw)
1385                 put(sink, " ");
1386     }
1387 
1388     /**
1389         `toString` is rarely directly invoked; the usual way of using it is via
1390         $(REF format, std, format):
1391      */
1392     @safe unittest
1393     {
1394         import std.format : format;
1395 
1396         auto x = BigInt("1_000_000");
1397         x *= 12345;
1398 
1399         assert(format("%d", x) == "12345000000");
1400         assert(format("%x", x) == "2_dfd1c040");
1401         assert(format("%X", x) == "2_DFD1C040");
1402         assert(format("%o", x) == "133764340100");
1403     }
1404 
1405     // for backwards compatibility, see unittest below
1406     /// ditto
1407     void toString(scope void delegate(scope const(char)[]) sink, string formatString) const
1408     {
1409         toString!(void delegate(scope const(char)[]))(sink, formatString);
1410     }
1411 
1412     // for backwards compatibility, see unittest below
1413     /// ditto
1414     void toString(scope void delegate(scope const(char)[]) sink, scope const ref FormatSpec!char f) const
1415     {
1416         toString!(void delegate(scope const(char)[]))(sink, f);
1417     }
1418 
1419     // Backwards compatibility test
1420     // BigInt.toString used to only accept a delegate sink function, but this does not work
1421     // well with attributes such as @safe. A template function toString was added that
1422     // works on OutputRanges, but when a delegate was passed in the form of an untyped
1423     // lambda such as `str => dst.put(str)` the parameter type was inferred as `void` and
1424     // the function failed to instantiate.
1425     @system unittest
1426     {
1427         import std.format.spec : FormatSpec;
1428         import std.array : appender;
1429         BigInt num = 503;
1430         auto dst = appender!string();
1431         num.toString(str => dst.put(str), null);
1432         assert(dst[] == "503");
1433         num = 504;
1434         auto f = FormatSpec!char("");
1435         num.toString(str => dst.put(str), f);
1436         assert(dst[] == "503504");
1437     }
1438 
1439     // Implement toHash so that BigInt works properly as an AA key.
1440     /**
1441         Returns: A unique hash of the `BigInt`'s value suitable for use in a hash
1442         table.
1443      */
1444     size_t toHash() const @safe pure nothrow @nogc
1445     {
1446         return data.toHash() + sign;
1447     }
1448 
1449     /**
1450         `toHash` is rarely directly invoked; it is implicitly used when
1451         BigInt is used as the key of an associative array.
1452      */
1453     @safe pure unittest
1454     {
1455         string[BigInt] aa;
1456         aa[BigInt(123)] = "abc";
1457         aa[BigInt(456)] = "def";
1458 
1459         assert(aa[BigInt(123)] == "abc");
1460         assert(aa[BigInt(456)] == "def");
1461     }
1462 
1463     /**
1464      * Gets the nth number in the underlying representation that makes up the whole
1465      * `BigInt`.
1466      *
1467      * Params:
1468      *     T = the type to view the underlying representation as
1469      *     n = The nth number to retrieve. Must be less than $(LREF ulongLength) or
1470      *     $(LREF uintLength) with respect to `T`.
1471      * Returns:
1472      *     The nth `ulong` in the representation of this `BigInt`.
1473      */
1474     T getDigit(T = ulong)(size_t n) const
1475     if (is(T == ulong) || is(T == uint))
1476     {
1477         static if (is(T == ulong))
1478         {
1479             assert(n < ulongLength(), "getDigit index out of bounds");
1480             return data.peekUlong(n);
1481         }
1482         else
1483         {
1484             assert(n < uintLength(), "getDigit index out of bounds");
1485             return data.peekUint(n);
1486         }
1487     }
1488 
1489     ///
1490     @safe pure unittest
1491     {
1492         auto a = BigInt("1000");
1493         assert(a.ulongLength() == 1);
1494         assert(a.getDigit(0) == 1000);
1495 
1496         assert(a.uintLength() == 1);
1497         assert(a.getDigit!uint(0) == 1000);
1498 
1499         auto b = BigInt("2_000_000_000_000_000_000_000_000_000");
1500         assert(b.ulongLength() == 2);
1501         assert(b.getDigit(0) == 4584946418820579328);
1502         assert(b.getDigit(1) == 108420217);
1503 
1504         assert(b.uintLength() == 3);
1505         assert(b.getDigit!uint(0) == 3489660928);
1506         assert(b.getDigit!uint(1) == 1067516025);
1507         assert(b.getDigit!uint(2) == 108420217);
1508     }
1509 
1510 private:
1511     void negate() @safe pure nothrow @nogc scope
1512     {
1513         if (!data.isZero())
1514             sign = !sign;
1515     }
1516     bool isZero() pure const nothrow @nogc @safe scope
1517     {
1518         return data.isZero();
1519     }
1520     alias isNegative = sign;
1521 
1522     // Generate a runtime error if division by zero occurs
1523     void checkDivByZero() pure const nothrow @safe scope
1524     {
1525         assert(!isZero(), "BigInt division by zero");
1526     }
1527 }
1528 
1529 ///
1530 @safe unittest
1531 {
1532     BigInt a = "9588669891916142";
1533     BigInt b = "7452469135154800";
1534     auto c = a * b;
1535     assert(c == BigInt("71459266416693160362545788781600"));
1536     auto d = b * a;
1537     assert(d == BigInt("71459266416693160362545788781600"));
1538     assert(d == c);
1539     d = c * BigInt("794628672112");
1540     assert(d == BigInt("56783581982794522489042432639320434378739200"));
1541     auto e = c + d;
1542     assert(e == BigInt("56783581982865981755459125799682980167520800"));
1543     auto f = d + c;
1544     assert(f == e);
1545     auto g = f - c;
1546     assert(g == d);
1547     g = f - d;
1548     assert(g == c);
1549     e = 12345678;
1550     g = c + e;
1551     auto h = g / b;
1552     auto i = g % b;
1553     assert(h == a);
1554     assert(i == e);
1555     BigInt j = "-0x9A56_57f4_7B83_AB78";
1556     BigInt k = j;
1557     j ^^= 11;
1558     assert(k ^^ 11 == j);
1559 }
1560 
1561 /**
1562 Params:
1563     x = The `BigInt` to convert to a decimal `string`.
1564 
1565 Returns:
1566     A `string` that represents the `BigInt` as a decimal number.
1567 
1568 */
1569 string toDecimalString(const(BigInt) x) pure nothrow @safe
1570 {
1571     auto buff = x.data.toDecimalString(x.isNegative ? 1 : 0);
1572     if (x.isNegative)
1573         buff[0] = '-';
1574     return buff;
1575 }
1576 
1577 ///
1578 @safe pure unittest
1579 {
1580     auto x = BigInt("123");
1581     x *= 1000;
1582     x += 456;
1583 
1584     auto xstr = x.toDecimalString();
1585     assert(xstr == "123456");
1586 }
1587 
1588 /**
1589 Params:
1590     x = The `BigInt` to convert to a hexadecimal `string`.
1591 
1592 Returns:
1593     A `string` that represents the `BigInt` as a hexadecimal (base 16)
1594     number in upper case.
1595 
1596 */
1597 string toHex(const(BigInt) x) pure @safe
1598 {
1599     import std.array : appender;
1600     auto outbuff = appender!string();
1601     x.toString(outbuff, "%X");
1602     return outbuff[];
1603 }
1604 
1605 ///
1606 @safe unittest
1607 {
1608     auto x = BigInt("123");
1609     x *= 1000;
1610     x += 456;
1611 
1612     auto xstr = x.toHex();
1613     assert(xstr == "1E240");
1614 }
1615 
1616 /** Returns the absolute value of x converted to the corresponding unsigned
1617 type.
1618 
1619 Params:
1620     x = The integral value to return the absolute value of.
1621 
1622 Returns:
1623     The absolute value of x.
1624 
1625 */
1626 Unsigned!T absUnsign(T)(T x)
1627 if (isIntegral!T)
1628 {
1629     static if (isSigned!T)
1630     {
1631         import std.conv : unsigned;
1632         /* This returns the correct result even when x = T.min
1633          * on two's complement machines because unsigned(T.min) = |T.min|
1634          * even though -T.min = T.min.
1635          */
1636         return unsigned((x < 0) ? cast(T)(0-x) : x);
1637     }
1638     else
1639     {
1640         return x;
1641     }
1642 }
1643 
1644 ///
1645 nothrow pure @safe
1646 unittest
1647 {
1648     assert((-1).absUnsign == 1);
1649     assert(1.absUnsign == 1);
1650 }
1651 
1652 nothrow pure @safe
1653 unittest
1654 {
1655     BigInt a, b;
1656     a = 1;
1657     b = 2;
1658     auto c = a + b;
1659     assert(c == 3);
1660 }
1661 
1662 nothrow pure @safe
1663 unittest
1664 {
1665     long a;
1666     BigInt b;
1667     auto c = a + b;
1668     assert(c == 0);
1669     auto d = b + a;
1670     assert(d == 0);
1671 }
1672 
1673 nothrow pure @safe
1674 unittest
1675 {
1676     BigInt x = 1, y = 2;
1677     assert(x <  y);
1678     assert(x <= y);
1679     assert(y >= x);
1680     assert(y >  x);
1681     assert(x != y);
1682 
1683     long r1 = x.toLong;
1684     assert(r1 == 1);
1685 
1686     BigInt r2 = 10 % x;
1687     assert(r2 == 0);
1688 
1689     BigInt r3 = 10 / y;
1690     assert(r3 == 5);
1691 
1692     BigInt[] arr = [BigInt(1)];
1693     auto incr = arr[0]++;
1694     assert(arr == [BigInt(2)]);
1695     assert(incr == BigInt(1));
1696 }
1697 
1698 @safe unittest
1699 {
1700     // Radix conversion
1701     assert( toDecimalString(BigInt("-1_234_567_890_123_456_789"))
1702         == "-1234567890123456789");
1703     assert( toHex(BigInt("0x1234567890123456789")) == "123_45678901_23456789");
1704     assert( toHex(BigInt("0x00000000000000000000000000000000000A234567890123456789"))
1705         == "A23_45678901_23456789");
1706     assert( toHex(BigInt("0x000_00_000000_000_000_000000000000_000000_")) == "0");
1707 
1708     assert(BigInt(-0x12345678).toInt() == -0x12345678);
1709     assert(BigInt(-0x12345678).toLong() == -0x12345678);
1710     assert(BigInt(0x1234_5678_9ABC_5A5AL).ulongLength == 1);
1711     assert(BigInt(0x1234_5678_9ABC_5A5AL).toLong() == 0x1234_5678_9ABC_5A5AL);
1712     assert(BigInt(-0x1234_5678_9ABC_5A5AL).toLong() == -0x1234_5678_9ABC_5A5AL);
1713     assert(BigInt(0xF234_5678_9ABC_5A5AL).toLong() == long.max);
1714     assert(BigInt(-0x123456789ABCL).toInt() == -int.max);
1715     char[] s1 = "123".dup; // https://issues.dlang.org/show_bug.cgi?id=8164
1716     assert(BigInt(s1) == 123);
1717     char[] s2 = "0xABC".dup;
1718     assert(BigInt(s2) == 2748);
1719 
1720     assert((BigInt(-2) + BigInt(1)) == BigInt(-1));
1721     BigInt a = ulong.max - 5;
1722     auto b = -long.max % a;
1723     assert( b == -long.max % (ulong.max - 5));
1724     b = long.max / a;
1725     assert( b == long.max /(ulong.max - 5));
1726     assert(BigInt(1) - 1 == 0);
1727     assert((-4) % BigInt(5) == -4); // https://issues.dlang.org/show_bug.cgi?id=5928
1728     assert(BigInt(-4) % BigInt(5) == -4);
1729     assert(BigInt(2)/BigInt(-3) == BigInt(0)); // https://issues.dlang.org/show_bug.cgi?id=8022
1730     assert(BigInt("-1") > long.min); // https://issues.dlang.org/show_bug.cgi?id=9548
1731 
1732     assert(toDecimalString(BigInt("0000000000000000000000000000000000000000001234567"))
1733         == "1234567");
1734 }
1735 
1736 @safe unittest // Minimum signed value bug tests.
1737 {
1738     assert(BigInt("-0x8000000000000000") == BigInt(long.min));
1739     assert(BigInt("-0x8000000000000000")+1 > BigInt(long.min));
1740     assert(BigInt("-0x80000000") == BigInt(int.min));
1741     assert(BigInt("-0x80000000")+1 > BigInt(int.min));
1742     assert(BigInt(long.min).toLong() == long.min); // lossy toLong bug for long.min
1743     assert(BigInt(int.min).toInt() == int.min); // lossy toInt bug for int.min
1744     assert(BigInt(long.min).ulongLength == 1);
1745     assert(BigInt(int.min).uintLength == 1); // cast/sign extend bug in opAssign
1746     BigInt a;
1747     a += int.min;
1748     assert(a == BigInt(int.min));
1749     a = int.min - BigInt(int.min);
1750     assert(a == 0);
1751     a = int.min;
1752     assert(a == BigInt(int.min));
1753     assert(int.min % (BigInt(int.min)-1) == int.min);
1754     assert((BigInt(int.min)-1)%int.min == -1);
1755 }
1756 
1757  // Recursive division (https://issues.dlang.org/show_bug.cgi?id=5568)
1758 @safe unittest
1759 {
1760     enum Z = 4843;
1761     BigInt m = (BigInt(1) << (Z*8) ) - 1;
1762     m -= (BigInt(1) << (Z*6)) - 1;
1763     BigInt oldm = m;
1764 
1765     BigInt a = (BigInt(1) << (Z*4) )-1;
1766     BigInt b = m % a;
1767     m /= a;
1768     m *= a;
1769     assert( m + b == oldm);
1770 
1771     m = (BigInt(1) << (4846 + 4843) ) - 1;
1772     a = (BigInt(1) << 4846 ) - 1;
1773     b = (BigInt(1) << (4846*2 + 4843)) - 1;
1774     BigInt c = (BigInt(1) << (4846*2 + 4843*2)) - 1;
1775     BigInt w =  c - b + a;
1776     assert(w % m == 0);
1777 
1778     // https://issues.dlang.org/show_bug.cgi?id=6819
1779     BigInt z1 = BigInt(10)^^64;
1780     BigInt w1 = BigInt(10)^^128;
1781     assert(z1^^2 == w1);
1782     BigInt z2 = BigInt(1)<<64;
1783     BigInt w2 = BigInt(1)<<128;
1784     assert(z2^^2 == w2);
1785     // https://issues.dlang.org/show_bug.cgi?id=7993
1786     BigInt n7793 = 10;
1787     assert( n7793 / 1 == 10);
1788     // https://issues.dlang.org/show_bug.cgi?id=7973
1789     auto a7973 = 10_000_000_000_000_000;
1790     const c7973 = 10_000_000_000_000_000;
1791     immutable i7973 = 10_000_000_000_000_000;
1792     BigInt v7973 = 2551700137;
1793     v7973 %= a7973;
1794     assert(v7973 == 2551700137);
1795     v7973 %= c7973;
1796     assert(v7973 == 2551700137);
1797     v7973 %= i7973;
1798     assert(v7973 == 2551700137);
1799     // https://issues.dlang.org/show_bug.cgi?id=8165
1800     BigInt[2] a8165;
1801     a8165[0] = a8165[1] = 1;
1802 }
1803 
1804 @safe unittest
1805 {
1806     import std.array;
1807     import std.format.write : formattedWrite;
1808 
1809     immutable string[][] table = [
1810     /*  fmt,        +10     -10 */
1811         ["%d",      "10",   "-10"],
1812         ["%+d",     "+10",  "-10"],
1813         ["%-d",     "10",   "-10"],
1814         ["%+-d",    "+10",  "-10"],
1815 
1816         ["%4d",     "  10", " -10"],
1817         ["%+4d",    " +10", " -10"],
1818         ["%-4d",    "10  ", "-10 "],
1819         ["%+-4d",   "+10 ", "-10 "],
1820 
1821         ["%04d",    "0010", "-010"],
1822         ["%+04d",   "+010", "-010"],
1823         ["%-04d",   "10  ", "-10 "],
1824         ["%+-04d",  "+10 ", "-10 "],
1825 
1826         ["% 04d",   " 010", "-010"],
1827         ["%+ 04d",  "+010", "-010"],
1828         ["%- 04d",  " 10 ", "-10 "],
1829         ["%+- 04d", "+10 ", "-10 "],
1830     ];
1831 
1832     auto w1 = appender!(char[])();
1833     auto w2 = appender!(char[])();
1834 
1835     foreach (entry; table)
1836     {
1837         immutable fmt = entry[0];
1838 
1839         formattedWrite(w1, fmt, BigInt(10));
1840         formattedWrite(w2, fmt, 10);
1841         assert(w1.data == w2.data);
1842         assert(w1.data == entry[1]);
1843         w1.clear();
1844         w2.clear();
1845 
1846         formattedWrite(w1, fmt, BigInt(-10));
1847         formattedWrite(w2, fmt, -10);
1848         assert(w1.data == w2.data);
1849         assert(w1.data == entry[2]);
1850         w1.clear();
1851         w2.clear();
1852     }
1853 }
1854 
1855 @safe unittest
1856 {
1857     import std.array;
1858     import std.format.write : formattedWrite;
1859 
1860     immutable string[][] table = [
1861     /*  fmt,        +10     -10 */
1862         ["%x",      "a",    "-a"],
1863         ["%+x",     "a",    "-a"],
1864         ["%-x",     "a",    "-a"],
1865         ["%+-x",    "a",    "-a"],
1866 
1867         ["%4x",     "   a", "  -a"],
1868         ["%+4x",    "   a", "  -a"],
1869         ["%-4x",    "a   ", "-a  "],
1870         ["%+-4x",   "a   ", "-a  "],
1871 
1872         ["%04x",    "000a", "-00a"],
1873         ["%+04x",   "000a", "-00a"],
1874         ["%-04x",   "a   ", "-a  "],
1875         ["%+-04x",  "a   ", "-a  "],
1876 
1877         ["% 04x",   "000a", "-00a"],
1878         ["%+ 04x",  "000a", "-00a"],
1879         ["%- 04x",  "a   ", "-a  "],
1880         ["%+- 04x", "a   ", "-a  "],
1881     ];
1882 
1883     auto w1 = appender!(char[])();
1884     auto w2 = appender!(char[])();
1885 
1886     foreach (entry; table)
1887     {
1888         immutable fmt = entry[0];
1889 
1890         formattedWrite(w1, fmt, BigInt(10));
1891         formattedWrite(w2, fmt, 10);
1892         assert(w1.data == w2.data);     // Equal only positive BigInt
1893         assert(w1.data == entry[1]);
1894         w1.clear();
1895         w2.clear();
1896 
1897         formattedWrite(w1, fmt, BigInt(-10));
1898         //formattedWrite(w2, fmt, -10);
1899         //assert(w1.data == w2.data);
1900         assert(w1.data == entry[2]);
1901         w1.clear();
1902         //w2.clear();
1903     }
1904 }
1905 
1906 @safe unittest
1907 {
1908     import std.array;
1909     import std.format.write : formattedWrite;
1910 
1911     immutable string[][] table = [
1912     /*  fmt,        +10     -10 */
1913         ["%X",      "A",    "-A"],
1914         ["%+X",     "A",    "-A"],
1915         ["%-X",     "A",    "-A"],
1916         ["%+-X",    "A",    "-A"],
1917 
1918         ["%4X",     "   A", "  -A"],
1919         ["%+4X",    "   A", "  -A"],
1920         ["%-4X",    "A   ", "-A  "],
1921         ["%+-4X",   "A   ", "-A  "],
1922 
1923         ["%04X",    "000A", "-00A"],
1924         ["%+04X",   "000A", "-00A"],
1925         ["%-04X",   "A   ", "-A  "],
1926         ["%+-04X",  "A   ", "-A  "],
1927 
1928         ["% 04X",   "000A", "-00A"],
1929         ["%+ 04X",  "000A", "-00A"],
1930         ["%- 04X",  "A   ", "-A  "],
1931         ["%+- 04X", "A   ", "-A  "],
1932     ];
1933 
1934     auto w1 = appender!(char[])();
1935     auto w2 = appender!(char[])();
1936 
1937     foreach (entry; table)
1938     {
1939         immutable fmt = entry[0];
1940 
1941         formattedWrite(w1, fmt, BigInt(10));
1942         formattedWrite(w2, fmt, 10);
1943         assert(w1.data == w2.data);     // Equal only positive BigInt
1944         assert(w1.data == entry[1]);
1945         w1.clear();
1946         w2.clear();
1947 
1948         formattedWrite(w1, fmt, BigInt(-10));
1949         //formattedWrite(w2, fmt, -10);
1950         //assert(w1.data == w2.data);
1951         assert(w1.data == entry[2]);
1952         w1.clear();
1953         //w2.clear();
1954     }
1955 }
1956 
1957 // https://issues.dlang.org/show_bug.cgi?id=6448
1958 @safe unittest
1959 {
1960     import std.array;
1961     import std.format.write : formattedWrite;
1962 
1963     auto w1 = appender!string();
1964     auto w2 = appender!string();
1965 
1966     int x = 100;
1967     formattedWrite(w1, "%010d", x);
1968     BigInt bx = x;
1969     formattedWrite(w2, "%010d", bx);
1970     assert(w1.data == w2.data);
1971     // https://issues.dlang.org/show_bug.cgi?id=8011
1972     BigInt y = -3;
1973     ++y;
1974     assert(y.toLong() == -2);
1975     y = 1;
1976     --y;
1977     assert(y.toLong() == 0);
1978     --y;
1979     assert(y.toLong() == -1);
1980     --y;
1981     assert(y.toLong() == -2);
1982 }
1983 
1984 @safe unittest
1985 {
1986     import std.math.algebraic : abs;
1987     auto r = abs(BigInt(-1000)); // https://issues.dlang.org/show_bug.cgi?id=6486
1988     assert(r == 1000);
1989 
1990     auto r2 = abs(const(BigInt)(-500)); // https://issues.dlang.org/show_bug.cgi?id=11188
1991     assert(r2 == 500);
1992     auto r3 = abs(immutable(BigInt)(-733)); // https://issues.dlang.org/show_bug.cgi?id=11188
1993     assert(r3 == 733);
1994 
1995     // opCast!bool
1996     BigInt one = 1, zero;
1997     assert(one && !zero);
1998 }
1999 
2000 // https://issues.dlang.org/show_bug.cgi?id=6850
2001 @safe unittest
2002 {
2003     pure long pureTest() {
2004         BigInt a = 1;
2005         BigInt b = 1336;
2006         a += b;
2007         return a.toLong();
2008     }
2009 
2010     assert(pureTest() == 1337);
2011 }
2012 
2013 // https://issues.dlang.org/show_bug.cgi?id=8435
2014 // https://issues.dlang.org/show_bug.cgi?id=10118
2015 @safe unittest
2016 {
2017     auto i = BigInt(100);
2018     auto j = BigInt(100);
2019 
2020     // Two separate BigInt instances representing same value should have same
2021     // hash.
2022     assert(typeid(i).getHash(&i) == typeid(j).getHash(&j));
2023     assert(typeid(i).compare(&i, &j) == 0);
2024 
2025     // BigInt AA keys should behave consistently.
2026     int[BigInt] aa;
2027     aa[BigInt(123)] = 123;
2028     assert(BigInt(123) in aa);
2029 
2030     aa[BigInt(123)] = 321;
2031     assert(aa[BigInt(123)] == 321);
2032 
2033     auto keys = aa.byKey;
2034     assert(keys.front == BigInt(123));
2035     keys.popFront();
2036     assert(keys.empty);
2037 }
2038 
2039 // https://issues.dlang.org/show_bug.cgi?id=11148
2040 @safe unittest
2041 {
2042     void foo(BigInt) {}
2043     const BigInt cbi = 3;
2044     immutable BigInt ibi = 3;
2045 
2046     foo(cbi);
2047     foo(ibi);
2048 
2049     import std.conv : to;
2050     import std.meta : AliasSeq;
2051 
2052     static foreach (T1; AliasSeq!(BigInt, const(BigInt), immutable(BigInt)))
2053     {
2054         static foreach (T2; AliasSeq!(BigInt, const(BigInt), immutable(BigInt)))
2055         {{
2056             T1 t1 = 2;
2057             T2 t2 = t1;
2058 
2059             T2 t2_1 = to!T2(t1);
2060             T2 t2_2 = cast(T2) t1;
2061 
2062             assert(t2 == t1);
2063             assert(t2 == 2);
2064 
2065             assert(t2_1 == t1);
2066             assert(t2_1 == 2);
2067 
2068             assert(t2_2 == t1);
2069             assert(t2_2 == 2);
2070         }}
2071     }
2072 
2073     BigInt n = 2;
2074     n *= 2;
2075     assert(n == 4);
2076 }
2077 
2078 // https://issues.dlang.org/show_bug.cgi?id=8167
2079 @safe unittest
2080 {
2081     BigInt a = BigInt(3);
2082     BigInt b = BigInt(a);
2083     assert(b == 3);
2084 }
2085 
2086 // https://issues.dlang.org/show_bug.cgi?id=9061
2087 @safe unittest
2088 {
2089     long l1 = 0x12345678_90ABCDEF;
2090     long l2 = 0xFEDCBA09_87654321;
2091     long l3 = l1 | l2;
2092     long l4 = l1 & l2;
2093     long l5 = l1 ^ l2;
2094 
2095     BigInt b1 = l1;
2096     BigInt b2 = l2;
2097     BigInt b3 = b1 | b2;
2098     BigInt b4 = b1 & b2;
2099     BigInt b5 = b1 ^ b2;
2100 
2101     assert(l3 == b3);
2102     assert(l4 == b4);
2103     assert(l5 == b5);
2104 }
2105 
2106 // https://issues.dlang.org/show_bug.cgi?id=11600
2107 @safe unittest
2108 {
2109     import std.conv;
2110     import std.exception : assertThrown;
2111 
2112     // Original bug report
2113     assertThrown!ConvException(to!BigInt("avadakedavra"));
2114 
2115     // Digit string lookalikes that are actually invalid
2116     assertThrown!ConvException(to!BigInt("0123hellothere"));
2117     assertThrown!ConvException(to!BigInt("-hihomarylowe"));
2118     assertThrown!ConvException(to!BigInt("__reallynow__"));
2119     assertThrown!ConvException(to!BigInt("-123four"));
2120 }
2121 
2122 // https://issues.dlang.org/show_bug.cgi?id=11583
2123 @safe unittest
2124 {
2125     BigInt x = 0;
2126     assert((x > 0) == false);
2127 }
2128 
2129 // https://issues.dlang.org/show_bug.cgi?id=13391
2130 @safe unittest
2131 {
2132     BigInt x1 = "123456789";
2133     BigInt x2 = "123456789123456789";
2134     BigInt x3 = "123456789123456789123456789";
2135 
2136     import std.meta : AliasSeq;
2137     static foreach (T; AliasSeq!(byte, ubyte, short, ushort, int, uint, long, ulong))
2138     {
2139         assert((x1 * T.max) / T.max == x1);
2140         assert((x2 * T.max) / T.max == x2);
2141         assert((x3 * T.max) / T.max == x3);
2142     }
2143 
2144     assert(x1 / -123456789 == -1);
2145     assert(x1 / 123456789U == 1);
2146     assert(x1 / -123456789L == -1);
2147     assert(x1 / 123456789UL == 1);
2148     assert(x2 / -123456789123456789L == -1);
2149     assert(x2 / 123456789123456789UL == 1);
2150 
2151     assert(x1 / uint.max == 0);
2152     assert(x1 / ulong.max == 0);
2153     assert(x2 / ulong.max == 0);
2154 
2155     x1 /= 123456789UL;
2156     assert(x1 == 1);
2157     x2 /= 123456789123456789UL;
2158     assert(x2 == 1);
2159 }
2160 
2161 // https://issues.dlang.org/show_bug.cgi?id=13963
2162 @safe unittest
2163 {
2164     BigInt x = 1;
2165     import std.meta : AliasSeq;
2166     static foreach (Int; AliasSeq!(byte, ubyte, short, ushort, int))
2167     {
2168         assert(is(typeof(x % Int(1)) == int));
2169     }
2170     assert(is(typeof(x % 1U) == long));
2171     assert(is(typeof(x % 1L) == long));
2172     assert(is(typeof(x % 1UL) == BigInt));
2173 
2174     auto x0 = BigInt(uint.max - 1);
2175     auto x1 = BigInt(8);
2176     assert(x1 / x == x1);
2177     auto x2 = -BigInt(long.min) + 1;
2178 
2179     // uint
2180     assert( x0 % uint.max ==  x0 % BigInt(uint.max));
2181     assert(-x0 % uint.max == -x0 % BigInt(uint.max));
2182     assert( x0 % uint.max ==  long(uint.max - 1));
2183     assert(-x0 % uint.max == -long(uint.max - 1));
2184 
2185     // long
2186     assert(x1 % 2L == 0L);
2187     assert(-x1 % 2L == 0L);
2188 
2189     assert(x1 % 3L == 2L);
2190     assert(x1 % -3L == 2L);
2191     assert(-x1 % 3L == -2L);
2192     assert(-x1 % -3L == -2L);
2193 
2194     assert(x1 % 11L == 8L);
2195     assert(x1 % -11L == 8L);
2196     assert(-x1 % 11L == -8L);
2197     assert(-x1 % -11L == -8L);
2198 
2199     // ulong
2200     assert(x1 % 2UL == BigInt(0));
2201     assert(-x1 % 2UL == BigInt(0));
2202 
2203     assert(x1 % 3UL == BigInt(2));
2204     assert(-x1 % 3UL == -BigInt(2));
2205 
2206     assert(x1 % 11UL == BigInt(8));
2207     assert(-x1 % 11UL == -BigInt(8));
2208 
2209     assert(x2 % ulong.max == x2);
2210     assert(-x2 % ulong.max == -x2);
2211 }
2212 
2213 // https://issues.dlang.org/show_bug.cgi?id=14124
2214 @safe unittest
2215 {
2216     auto x = BigInt(-3);
2217     x %= 3;
2218     assert(!x.isNegative);
2219     assert(x.isZero);
2220 
2221     x = BigInt(-3);
2222     x %= cast(ushort) 3;
2223     assert(!x.isNegative);
2224     assert(x.isZero);
2225 
2226     x = BigInt(-3);
2227     x %= 3L;
2228     assert(!x.isNegative);
2229     assert(x.isZero);
2230 
2231     x = BigInt(3);
2232     x %= -3;
2233     assert(!x.isNegative);
2234     assert(x.isZero);
2235 }
2236 
2237 // https://issues.dlang.org/show_bug.cgi?id=15678
2238 @safe unittest
2239 {
2240     import std.exception : assertThrown;
2241     assertThrown!ConvException(BigInt(""));
2242     assertThrown!ConvException(BigInt("0x1234BARF"));
2243     assertThrown!ConvException(BigInt("1234PUKE"));
2244 }
2245 
2246 // https://issues.dlang.org/show_bug.cgi?id=6447
2247 @safe unittest
2248 {
2249     import std.algorithm.comparison : equal;
2250     import std.range : iota;
2251 
2252     auto s = BigInt(1_000_000_000_000);
2253     auto e = BigInt(1_000_000_000_003);
2254     auto r = iota(s, e);
2255     assert(r.equal([
2256         BigInt(1_000_000_000_000),
2257         BigInt(1_000_000_000_001),
2258         BigInt(1_000_000_000_002)
2259     ]));
2260 }
2261 
2262 // https://issues.dlang.org/show_bug.cgi?id=17330
2263 @safe unittest
2264 {
2265     auto b = immutable BigInt("123");
2266     assert(b == 123);
2267 }
2268 
2269 // https://issues.dlang.org/show_bug.cgi?id=14767
2270 @safe pure unittest
2271 {
2272     static immutable a = BigInt("340282366920938463463374607431768211455");
2273     assert(a == BigInt("340282366920938463463374607431768211455"));
2274 
2275     BigInt plusTwo(in BigInt n)
2276     {
2277         return n + 2;
2278     }
2279 
2280     enum BigInt test1 = BigInt(123);
2281     enum BigInt test2 = plusTwo(test1);
2282     assert(test2 == 125);
2283 }
2284 
2285 /**
2286  * Finds the quotient and remainder for the given dividend and divisor in one operation.
2287  *
2288  * Params:
2289  *     dividend = the $(LREF BigInt) to divide
2290  *     divisor = the $(LREF BigInt) to divide the dividend by
2291  *     quotient = is set to the result of the division
2292  *     remainder = is set to the remainder of the division
2293  */
2294 void divMod(const BigInt dividend, const BigInt divisor, out BigInt quotient, out BigInt remainder) pure nothrow @safe
2295 {
2296     BigUint q, r;
2297     BigUint.divMod(dividend.data, divisor.data, q, r);
2298     quotient.sign = dividend.sign != divisor.sign;
2299     quotient.data = q;
2300     remainder.sign = r.isZero() ? false : dividend.sign;
2301     remainder.data = r;
2302 }
2303 
2304 ///
2305 @safe pure nothrow unittest
2306 {
2307     auto a = BigInt(123);
2308     auto b = BigInt(25);
2309     BigInt q, r;
2310 
2311     divMod(a, b, q, r);
2312 
2313     assert(q == 4);
2314     assert(r == 23);
2315     assert(q * b + r == a);
2316 }
2317 
2318 // https://issues.dlang.org/show_bug.cgi?id=18086
2319 @safe pure nothrow unittest
2320 {
2321     BigInt q = 1;
2322     BigInt r = 1;
2323     BigInt c = 1024;
2324     BigInt d = 100;
2325 
2326     divMod(c, d, q, r);
2327     assert(q ==  10);
2328     assert(r ==  24);
2329     assert((q * d + r) == c);
2330 
2331     divMod(c, -d, q, r);
2332     assert(q == -10);
2333     assert(r ==  24);
2334     assert(q * -d + r == c);
2335 
2336     divMod(-c, -d, q, r);
2337     assert(q ==  10);
2338     assert(r == -24);
2339     assert(q * -d + r == -c);
2340 
2341     divMod(-c, d, q, r);
2342     assert(q == -10);
2343     assert(r == -24);
2344     assert(q * d + r == -c);
2345 }
2346 
2347 // https://issues.dlang.org/show_bug.cgi?id=22771
2348 @safe pure nothrow unittest
2349 {
2350     BigInt quotient, remainder;
2351     divMod(BigInt(-50), BigInt(1), quotient, remainder);
2352     assert(remainder == 0);
2353 }
2354 
2355 // https://issues.dlang.org/show_bug.cgi?id=19740
2356 @safe unittest
2357 {
2358     BigInt a = BigInt(
2359         "241127122100380210001001124020210001001100000200003101000062221012075223052000021042250111300200000000000" ~
2360         "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
2361     BigInt b = BigInt(
2362         "700200000000500418321000401140010110000022007221432000000141020011323301104104060202100200457210001600142" ~
2363         "000001012245300100001110215200000000120000000000000000000000000000000000000000000000000000000000000000000" ~
2364         "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
2365 
2366     BigInt c = a * b;
2367     assert(c == BigInt(
2368         "1688372108948068874722901180228375682334987075822938736581472847151834613694489486296103575639363261807341" ~
2369         "3910091006778604956808730652275328822700182498926542563654351871390166691461743896850906716336187966456064" ~
2370         "2702007176328110013356024000000000000000000000000000000000000000000000000000000000000000000000000000000000" ~
2371         "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" ~
2372         "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
2373 }
2374 
2375 @safe unittest
2376 {
2377     auto n = BigInt("1234"d);
2378 }
2379 
2380 /**
2381 Fast power modulus calculation for $(LREF BigInt) operands.
2382 Params:
2383      base = the $(LREF BigInt) is basic operands.
2384      exponent = the $(LREF BigInt) is power exponent of base.
2385      modulus = the $(LREF BigInt) is modules to be modular of base ^ exponent.
2386 Returns:
2387      The power modulus value of (base ^ exponent) % modulus.
2388 */
2389 BigInt powmod(BigInt base, BigInt exponent, BigInt modulus) pure nothrow @safe
2390 {
2391     BigInt result = 1;
2392 
2393     while (exponent)
2394     {
2395         if (exponent.data.peekUint(0) & 1)
2396         {
2397             result = (result * base) % modulus;
2398         }
2399 
2400         auto tmp = base % modulus;
2401         base = (tmp * tmp) % modulus;
2402         exponent >>= 1;
2403     }
2404 
2405     return result;
2406 }
2407 
2408 /// for powmod
2409 @safe unittest
2410 {
2411     BigInt base = BigInt("123456789012345678901234567890");
2412     BigInt exponent = BigInt("1234567890123456789012345678901234567");
2413     BigInt modulus = BigInt("1234567");
2414 
2415     BigInt result = powmod(base, exponent, modulus);
2416     assert(result == 359079);
2417 }