Old snapshot `BigInteger-2004.12.16'; see the ChangeLog file.
[bigint/bigint.git] / BigUnsigned.cpp
1 /*
2 * Matt McCutchen's Big Integer Library
3 * http://mysite.verizon.net/mccutchen/bigint/
4 */
5
6 #include "BigUnsigned.h"
7
8 // MANAGEMENT
9
10 // This routine is called to ensure the number array is at least a
11 // certain size before the result of an operation is written over it. 
12 void BigUnsigned::allocate(BlkNum c) {
13         // If the requested capacity is more than the current capacity...
14         if (c > cap) {
15                 // Delete the old number array
16                 delete [] blk;
17                 // Allocate the new array
18                 cap = c;
19                 blk = new Blk[cap];
20         }
21 }
22
23 // This routine is called to ensure the number array is at least a
24 // certain size without losing its contents.
25 void BigUnsigned::allocateAndCopy(BlkNum c) {
26         // If the requested capacity is more than the current capacity...
27         if (c > cap) {
28                 Blk *oldBlk = blk;
29                 // Allocate the new number array
30                 cap = c;
31                 blk = new Blk[cap];
32                 // Copy number blocks
33                 BlkNum i;
34                 Blk *blkI;
35                 const Blk *oldBlkI;
36                 for (i = 0, blkI = blk, oldBlkI = oldBlk; i < len; i++, blkI++, oldBlkI++)
37                         *blkI = *oldBlkI;
38                 // Delete the old array
39                 delete [] oldBlk;
40         }
41 }
42
43 // Copy constructor
44 BigUnsigned::BigUnsigned(const BigUnsigned &x) : len(x.len) {
45         // Create number array
46         cap = len;
47         blk = new Blk[cap];
48         // Copy number blocks
49         BlkNum i;
50         Blk *blkI;
51         const Blk *xBlkI;
52         for (i = 0, blkI = blk, xBlkI = x.blk; i < len; i++, blkI++, xBlkI++)
53                 *blkI = *xBlkI;
54 }
55
56 // Assignment operator
57 void BigUnsigned::operator=(const BigUnsigned &x) {
58         // Calls like a = a have no effect
59         if (this == &x)
60                 return;
61         // Copy length
62         len = x.len;
63         // Expand number array if necessary
64         allocate(len);
65         // Copy number blocks
66         BlkNum i;
67         Blk *blkI;
68         const Blk *xBlkI;
69         for (i = 0, blkI = blk, xBlkI = x.blk; i < len; i++, blkI++, xBlkI++)
70                 *blkI = *xBlkI;
71 }
72
73 // Constructor from an array of blocks
74 BigUnsigned::BigUnsigned(const Blk *b, BlkNum l) : cap(l), len(l) {
75         // Create number array
76         blk = new Blk[cap];
77         // Copy number blocks
78         BlkNum i;
79         Blk *blkI;
80         const Blk *bI;
81         for (i = 0, blkI = blk, bI = b; i < len; i++, blkI++, bI++)
82                 *blkI = *bI;
83         zapLeadingZeros();
84 }
85
86 /*
87 * The steps for construction of a BigUnsigned
88 * from an integral value x are as follows:
89 * 1. If x is zero, create an empty BigUnsigned and stop.
90 * 2. If x is negative, throw an exception.
91 * 3. Allocate a one-block number array.
92 * 4. If x is of a signed type, convert x to the unsigned
93 *    type of the same length.
94 * 5. Expand x to a Blk, and store it in the number array.
95 */
96
97 BigUnsigned::BigUnsigned(unsigned long x) {
98         if (x == 0) {
99                 cap = 0;
100                 blk = new Blk[0];
101                 len = 0;
102         } else {
103                 cap = 1;
104                 blk = new Blk[1];
105                 len = 1;
106                 *blk = Blk(x);
107         }
108 }
109
110 BigUnsigned::BigUnsigned(long x) {
111         if (x == 0) {
112                 cap = 0;
113                 blk = new Blk[0];
114                 len = 0;
115         } else if (x > 0) {
116                 cap = 1;
117                 blk = new Blk[1];
118                 len = 1;
119                 *blk = Blk(x);
120         } else
121     throw "BigUnsigned::BigUnsigned(long): Cannot construct a BigUnsigned from a negative number";
122 }
123
124 BigUnsigned::BigUnsigned(unsigned int x) {
125         if (x == 0) {
126                 cap = 0;
127                 blk = new Blk[0];
128                 len = 0;
129         } else {
130                 cap = 1;
131                 blk = new Blk[1];
132                 len = 1;
133                 *blk = Blk(x);
134         }
135 }
136
137 BigUnsigned::BigUnsigned(int x) {
138         if (x == 0) {
139                 cap = 0;
140                 blk = new Blk[0];
141                 len = 0;
142         } else if (x > 0) {
143                 cap = 1;
144                 blk = new Blk[1];
145                 len = 1;
146                 *blk = Blk(x);
147         } else
148     throw "BigUnsigned::BigUnsigned(int): Cannot construct a BigUnsigned from a negative number";
149 }
150
151 BigUnsigned::BigUnsigned(unsigned short x) {
152         if (x == 0) {
153                 cap = 0;
154                 blk = new Blk[0];
155                 len = 0;
156         } else {
157                 cap = 1;
158                 blk = new Blk[1];
159                 len = 1;
160                 *blk = Blk(x);
161         }
162 }
163
164 BigUnsigned::BigUnsigned(short x) {
165         if (x == 0) {
166                 cap = 0;
167                 blk = new Blk[0];
168                 len = 0;
169         } else if (x > 0) {
170                 cap = 1;
171                 blk = new Blk[1];
172                 len = 1;
173                 *blk = Blk(x);
174         } else
175     throw "BigUnsigned::BigUnsigned(short): Cannot construct a BigUnsigned from a negative number";
176 }
177
178 // CONVERTERS
179 /*
180 * The steps for conversion of a BigUnsigned to an
181 * integral type are as follows:
182 * 1. If the BigUnsigned is zero, return zero.
183 * 2. If it is more than one block long or its lowest
184 *    block has bits set out of the range of the target
185 *    type, throw an exception.
186 * 3. Otherwise, convert the lowest block to the
187 *    target type and return it.
188 */
189
190 namespace {
191         // These masks are used to test whether a Blk has bits
192         // set out of the range of a smaller integral type.  Note
193         // that this range is not considered to include the sign bit.
194         const BigUnsigned::Blk  lMask = ~0 >> 1;
195         const BigUnsigned::Blk uiMask = (unsigned int)(~0);
196         const BigUnsigned::Blk  iMask = uiMask >> 1;
197         const BigUnsigned::Blk usMask = (unsigned short)(~0);
198         const BigUnsigned::Blk  sMask = usMask >> 1;
199 }
200
201 BigUnsigned::operator unsigned long() const {
202         if (len == 0)
203                 return 0;
204         else if (len == 1)
205                 return (unsigned long) *blk;
206         else
207                 throw "BigUnsigned::operator unsigned long: Value is too big for an unsigned long";
208 }
209
210 BigUnsigned::operator long() const {
211         if (len == 0)
212                 return 0;
213         else if (len == 1 && (*blk & lMask) == *blk)
214                 return (long) *blk;
215         else
216                 throw "BigUnsigned::operator long: Value is too big for a long";
217 }
218
219 BigUnsigned::operator unsigned int() const {
220         if (len == 0)
221                 return 0;
222         else if (len == 1 && (*blk & uiMask) == *blk)
223                 return (unsigned int) *blk;
224         else
225                 throw "BigUnsigned::operator unsigned int: Value is too big for an unsigned int";
226 }
227
228 BigUnsigned::operator int() const {
229         if (len == 0)
230                 return 0;
231         else if (len == 1 && (*blk & iMask) == *blk)
232                 return (int) *blk;
233         else
234                 throw "BigUnsigned::operator int: Value is too big for an int";
235 }
236
237 BigUnsigned::operator unsigned short() const {
238         if (len == 0)
239                 return 0;
240         else if (len == 1 && (*blk & usMask) == *blk)
241                 return (unsigned short) *blk;
242         else
243                 throw "BigUnsigned::operator unsigned short: Value is too big for an unsigned short";
244 }
245
246 BigUnsigned::operator short() const {
247         if (len == 0)
248                 return 0;
249         else if (len == 1 && (*blk & sMask) == *blk)
250                 return (short) *blk;
251         else
252                 throw "BigUnsigned::operator short: Value is too big for a short";
253 }
254
255 // COMPARISON
256 BigUnsigned::CmpRes BigUnsigned::compareTo(const BigUnsigned &x) const {
257         // A bigger length implies a bigger number.
258         if (len < x.len)
259                 return less;
260         else if (len > x.len)
261                 return greater;
262         else {
263                 // Compare blocks one by one from left to right.
264                 BlkNum i = len;
265                 const Blk *blkI = blk + len;
266                 const Blk *xBlkI = x.blk + len;
267                 while (i > 0) {
268                         i--;
269                         blkI--;
270                         xBlkI--;
271                         if (*blkI == *xBlkI)
272                                 continue;
273                         else if (*blkI > *xBlkI)
274                                 return greater;
275                         else
276                                 return less;
277                 }
278                 // If no blocks differed, the numbers are equal.
279                 return equal;
280         }
281 }
282
283 // PUT-HERE OPERATIONS
284
285 // Addition
286 void BigUnsigned::add(const BigUnsigned &a, const BigUnsigned &b) {
287         // Block unsafe calls
288         if (this == &a || this == &b)
289                 throw "BigUnsigned::add: One of the arguments is the invoked object";
290         // If one argument is zero, copy the other.
291         if (a.len == 0) {
292                 operator =(b);
293                 return;
294         } else if (b.len == 0) {
295                 operator =(a);
296                 return;
297         }
298         // Carries in and out of an addition stage
299         bool carryIn, carryOut;
300         Blk temp;
301         BlkNum i;
302         // a2 points to the longer input, b2 points to the shorter
303         const BigUnsigned *a2, *b2;
304         if (a.len >= b.len) {
305                 a2 = &a;
306                 b2 = &b;
307         } else {
308                 a2 = &b;
309                 b2 = &a;
310         }
311         // These point directly to the position of interest in the
312         // corresponding block arrays, for faster access.
313         Blk *blkI;
314         const Blk *a2BlkI, *b2BlkI;
315         // Set prelimiary length and make room in this BigUnsigned
316         len = a2->len + 1;
317         allocate(len);
318         // For each block index that is present in both inputs...
319         for (i = 0, blkI = blk, a2BlkI = a2->blk, b2BlkI = b2->blk,
320         carryIn = false; i < b2->len; i++, blkI++, a2BlkI++, b2BlkI++) {
321                 // Add input blocks
322                 temp = *a2BlkI + *b2BlkI;
323                 // If a rollover occurred, the result is less than either input.
324                 // This test is used many times in the BigUnsigned code.
325                 carryOut = (temp < *a2BlkI);
326                 // If a carry was input, handle it
327                 if (carryIn) {
328                         temp++;
329                         carryOut |= (temp == 0);
330                 }
331                 *blkI = temp; // Save the addition result
332                 carryIn = carryOut; // Pass the carry along
333         }
334         // If there is a carry left over, increase blocks until
335         // one does not roll over.
336         for (; i < a2->len && carryIn; i++, blkI++, a2BlkI++) {
337                 temp = *a2BlkI + 1;
338                 carryIn = (temp == 0);
339                 *blkI = temp;
340         }
341         // If the carry was resolved but the larger number
342         // still has blocks, copy them over.
343         for (; i < a2->len; i++, blkI++, a2BlkI++)
344                 *blkI = *a2BlkI;
345         // Set the extra block if there's still a carry, decrease length otherwise
346         if (carryIn)
347                 *blkI = 1;
348         else
349                 len--;
350 }
351
352 // Subtraction
353 void BigUnsigned::subtract(const BigUnsigned &a, const BigUnsigned &b) {
354         // Block unsafe calls
355         if (this == &a || this == &b)
356                 throw "BigUnsigned::subtract: One of the arguments is the invoked object";
357         // If b is zero, copy a.  If a is shorter than b, the result is negative.
358         if (b.len == 0) {
359                 operator =(a);
360                 return;
361         } else if (a.len < b.len)
362     throw "BigUnsigned::subtract: Negative result in unsigned calculation";
363         bool borrowIn, borrowOut;
364         Blk temp;
365         BlkNum i;
366         // These point directly to the position of interest in the
367         // corresponding block arrays, for faster access.
368         Blk *blkI;
369         const Blk *aBlkI, *bBlkI;
370         // Set preliminary length and make room
371         len = a.len;
372         allocate(len);
373         // For each block index that is present in both inputs...
374         for (i = 0, blkI = blk, aBlkI = a.blk, bBlkI = b.blk,
375         borrowIn = false; i < b.len; i++, blkI++, aBlkI++, bBlkI++) {
376                 temp = *aBlkI - *bBlkI;
377                 // If a reverse rollover occurred, the result is greater than the block from a.
378                 borrowOut = (temp > *aBlkI);
379                 // Handle an incoming borrow
380                 if (borrowIn) {
381                         borrowOut |= (temp == 0);
382                         temp--;
383                 }
384                 *blkI = temp; // Save the subtraction result
385                 borrowIn = borrowOut; // Pass the borrow along
386         }
387         // If there is a borrow left over, decrease blocks until
388         // one does not reverse rollover.
389         for (; i < a.len && borrowIn; i++, blkI++, aBlkI++) {
390                 borrowIn = (*aBlkI == 0);
391                 *blkI = *aBlkI - 1;
392         }
393         // If there's still a borrow, the result is negative.
394         // Throw an exception, but zero out this object first.
395         if (borrowIn) {
396                 len = 0;
397                 throw "BigUnsigned::subtract: Negative result in unsigned calculation";
398         } else // Copy over the rest of the blocks
399     for (; i < a.len; i++, blkI++, aBlkI++)
400                 *blkI = *aBlkI;
401         // Zap leading zeros
402         zapLeadingZeros();
403 }
404
405 // Multiplication
406 void BigUnsigned::multiply(const BigUnsigned &a, const BigUnsigned &b) {
407         // Block unsafe calls
408         if (this == &a || this == &b)
409                 throw "BigUnsigned::multiply: One of the arguments is the invoked object";
410         // If either a or b is zero, set to zero.
411         if (a.len == 0 || b.len == 0) {
412                 len = 0;
413                 return;
414         }
415         // Overall method: this = 0, then for each 1-bit of a, add b
416         // to this shifted the appropriate amount.
417         // Variables for the calculation
418         BlkNum i, j;
419         unsigned int i2;
420         Blk aBlk, bHigh, temp;
421         bool carryIn, carryOut;
422         // These point directly to the positions of interest in the
423         // corresponding block arrays, for faster access.
424         Blk *blkI, *blkK;
425         const Blk *aBlkI, *bBlkJ;
426         // Set preliminary length and make room
427         len = a.len + b.len;
428         allocate(len);
429         // Zero out this object
430         for (i = 0, blkI = blk; i < len; i++, blkI++)
431                 *blkI = 0;
432         // For each block of the first number...
433         for (i = 0, blkI = blk, aBlkI = a.blk; i < a.len; i++, blkI++, aBlkI++)
434                 // For each 1-bit of that block...
435     for (i2 = 0, aBlk = *aBlkI; aBlk != 0; i2++, aBlk >>= 1) {
436                 if ((aBlk & 1) == 0)
437                         continue;
438                 /* Add b to this, shifted left i blocks and i2 bits.
439                 * j is the index in b, and k = i + j is the index in this.
440                 * The low bits of b.blk[j] are shifted and added to blk[k].
441                 * bHigh is used to carry the high bits to the next addition. */
442                 carryIn = false;
443                 bHigh = 0;
444                 for (j = 0, bBlkJ = b.blk, blkK = blkI; j < b.len; j++, bBlkJ++, blkK++) {
445                         temp = *blkK + ((*bBlkJ << i2) | bHigh);
446                         carryOut = (temp < *blkK);
447                         if (carryIn) {
448                                 temp++;
449                                 carryOut |= (temp == 0);
450                         }
451                         *blkK = temp;
452                         carryIn = carryOut;
453                         bHigh = (i2 == 0) ? 0 : *bBlkJ >> (8 * sizeof(Blk) - i2);
454                 }
455                 temp = *blkK + bHigh;
456                 carryOut = (temp < *blkK);
457                 if (carryIn) {
458                         temp++;
459                         carryOut |= (temp == 0);
460                 }
461                 *blkK = temp;
462                 carryIn = carryOut;
463                 for (; carryIn; blkK++) {
464                         (*blkK)++;
465                         carryIn = (*blkK == 0);
466                 }
467     }
468         // Zap leading zero
469         if (blk[len - 1] == 0)
470                 len--;
471 }
472
473 // Division
474 void BigUnsigned::divide(const BigUnsigned &a, const BigUnsigned &b) {
475         // Note: This is integer division.  Any fractional part
476         // of the result is truncated.
477         // Block unsafe calls
478         if (this == &a || this == &b)
479                 throw "BigUnsigned::divide: One of the arguments is the invoked object";
480         // If b is zero, throw an exception.  If a is zero, set to zero.
481         else if (b.len == 0)
482                 throw "BigUnsigned::divide: Division by zero";
483         else if (a.len < b.len) {
484                 len = 0;
485                 return;
486         }
487         /* Overall method: Subtract b, shifted varying amounts to
488         * the left, from a, setting the bit in the quotient
489         * whenever the subtraction succeeds. */
490         // Variables for the calculation
491         BlkNum i, j, k;
492         unsigned int i2;
493         Blk bHigh, temp;
494         bool borrowIn, borrowOut;
495         // work1 is a copy of a that can be modified
496         // after each successful subtraction.
497         Blk *work1 = new Blk[a.len + 1];
498         Blk *work1I = work1;
499         const Blk *aBlkI = a.blk;
500         for (i = 0; i < a.len; i++, work1I++, aBlkI++)
501                 *work1I = *aBlkI;
502         *work1I = 0;
503         // work2 holds part of the result of a subtraction
504         Blk *work2 = new Blk[a.len + 1];
505         // These point directly to the positions of interest in the
506         // corresponding block arrays, for faster access.
507         Blk *blkI, *work1K, *work2J;
508         const Blk *bBlkJ;
509         // Set preliminary length and make room
510         len = a.len - b.len + 1;
511         allocate(len);
512         // For each possible left-shift of b in blocks...
513         i = len;
514         blkI = blk + len;
515         work1I = work1 + len;
516         while (i > 0) {
517                 i--;
518                 blkI--;
519                 work1I--;
520                 // For each possible left-shift of b in bits...
521                 *blkI = 0;
522                 i2 = 8 * sizeof(Blk);
523                 while (i2 > 0) {
524                         i2--;
525                         // Subtract b, shifted left i blocks and i2 bits, from work1
526                         // and store the answer in work2.  See note in BigUnsigned::multiply.
527                         bHigh = 0;
528                         for (j = 0, bBlkJ = b.blk, work2J = work2, k = i, work1K = work1I,
529                         borrowIn = false; j < b.len; j++, bBlkJ++, work2J++, k++, work1K++) {
530                                 temp = *work1K - ((*bBlkJ << i2) | bHigh);
531                                 borrowOut = (temp > *work1K);
532                                 if (borrowIn) {
533                                         borrowOut |= (temp == 0);
534                                         temp--;
535                                 }
536                                 *work2J = temp;
537                                 borrowIn = borrowOut;
538                                 bHigh = (i2 == 0) ? 0 : *bBlkJ >> (8 * sizeof(Blk) - i2);
539                         }
540                         temp = *work1K - bHigh;
541                         borrowOut = (temp > *work1K);
542                         if (borrowIn) {
543                                 borrowOut |= (temp == 0);
544                                 temp--;
545                         }
546                         *work2J = temp;
547                         borrowIn = borrowOut;
548                         j++;
549                         work2J++;
550                         k++;
551                         work1K++;
552                         for (; k < a.len + 1 && borrowIn; j++, work2J++, k++, work1K++) {
553                                 borrowIn = (*work1K == 0);
554                                 *work2J = *work1K - 1;
555                         }
556                         /* If the subtraction was performed successfully, set bit i2
557                         * in block i of the quotient, and copy the changed portion of
558                         * work2 back to work1. Otherwise, reset that bit and move on. */
559                         if (!borrowIn) {
560                                 *blkI |= (1 << i2);
561                                 while (j > 0) {
562                                         j--;
563                                         work2J--;
564                                         k--;
565                                         work1K--;
566                                         *work1K = *work2J;
567                                 }
568                         }
569                 }
570         }
571         // Zap leading zero
572         if (blk[len - 1] == 0)
573                 len--;
574         // Deallocate temporary arrays.
575         // (Thanks to Brad Spencer for noticing my accidental omission of this!)
576         delete [] work1;
577         delete [] work2;
578 }
579
580 // Modulo
581 void BigUnsigned::modulo(const BigUnsigned &a, const BigUnsigned &b) {
582         /* Note that the mathematical definition of mod is somewhat
583         * different from the way the normal C++ % operator behaves.
584         * This function does it the mathematical way. */
585         // Block unsafe calls
586         if (this == &a || this == &b)
587                 throw "BigUnsigned::modulo: One of the arguments is the invoked object";
588         // If b is zero, copy a and return.  By the mathematical definition,
589         // x mod 0 = x, though the normal C++ % would throw an exception.
590         else if (b.len == 0) {
591                 len = 0;
592                 return;
593                 // If a is zero, set to zero and return.
594         } else if (a.len < b.len) {
595                 operator =(a);
596                 return;
597         }
598         /* Overall method: Copy a into this.  Then subtract b,
599         * shifted varying amounts to the left, from this.
600         * When no more subtraction is possible, stop; this
601         * will contain the remainder.
602         * This is very similar to the division routine, except
603         * that whether or not a subtraction succeeds is ignored,
604         * and "this" serves the purpose of work1. */
605         // Variables for the calculation
606         BlkNum i, j, k;
607         unsigned int i2;
608         Blk bHigh, temp;
609         bool borrowIn, borrowOut;
610         allocate(a.len + 1);
611         operator =(a);
612         blk[len] = 0;
613         // work2 holds part of the result of a subtraction
614         Blk *work2 = new Blk[a.len + 1];
615         // These point directly to the positions of interest in the
616         // corresponding block arrays, for faster access.
617         Blk *blkI, *blkK, *work2J;
618         const Blk *bBlkJ;
619         // For each possible left-shift of b in blocks...
620         i = len;
621         blkI = blk + len;
622         while (i > 0) {
623                 i--;
624                 blkI--;
625                 // For each possible left-shift of b in bits...
626                 i2 = 8 * sizeof(Blk);
627                 while (i2 > 0) {
628                         i2--;
629                         // Subtract b, shifted left i blocks and i2 bits, from work1
630                         // and store the answer in work2.  See note in BigUnsigned::multiply.
631                         bHigh = 0;
632                         for (j = 0, bBlkJ = b.blk, work2J = work2, k = i, blkK = blkI,
633                         borrowIn = false; j < b.len; j++, bBlkJ++, work2J++, k++, blkK++) {
634                                 temp = *blkK - ((*bBlkJ << i2) | bHigh);
635                                 borrowOut = (temp > *blkK);
636                                 if (borrowIn) {
637                                         borrowOut |= (temp == 0);
638                                         temp--;
639                                 }
640                                 *work2J = temp;
641                                 borrowIn = borrowOut;
642                                 bHigh = (i2 == 0) ? 0 : *bBlkJ >> (8 * sizeof(Blk) - i2);
643                         }
644                         temp = *blkK - bHigh;
645                         borrowOut = (temp > *blkK);
646                         if (borrowIn) {
647                                 borrowOut |= (temp == 0);
648                                 temp--;
649                         }
650                         *work2J = temp;
651                         borrowIn = borrowOut;
652                         j++;
653                         work2J++;
654                         k++;
655                         blkK++;
656                         for (; k < a.len + 1 && borrowIn; j++, work2J++, k++, blkK++) {
657                                 borrowIn = (*blkK == 0);
658                                 *work2J = *blkK - 1;
659                         }
660                         // If the subtraction was performed successfully, set bit i2
661                         // in block i of the quotient, and copy the changed portion of
662                         // work2 back to this.
663                         if (!borrowIn)
664                         while (j > 0) {
665                                 j--;
666                                 work2J--;
667                                 k--;
668                                 blkK--;
669                                 *blkK = *work2J;
670                         }
671                 }
672         }
673         // Blocks higher than the last block of the modulus are zero.
674         len = b.len;
675         // Zap leading zeros
676         zapLeadingZeros();
677 }
678
679 // Bitwise and
680 void BigUnsigned::bitAnd(const BigUnsigned &a, const BigUnsigned &b) {
681         // Block unsafe calls
682         if (this == &a || this == &b)
683                 throw "BigUnsigned::bitAnd: One of the arguments is the invoked object";
684         len = (a.len >= b.len) ? b.len : a.len;
685         allocate(len);
686         BlkNum i;
687         Blk *blkI;
688         const Blk *aBlkI, *bBlkI;
689         for (i = 0, blkI = blk, aBlkI = a.blk, bBlkI = b.blk;
690         i < len; i++, blkI++, aBlkI++, bBlkI++)
691     *blkI = *aBlkI & *bBlkI;
692         zapLeadingZeros();
693 }
694
695 // Bitwise or
696 void BigUnsigned::bitOr(const BigUnsigned &a, const BigUnsigned &b) {
697         // Block unsafe calls
698         if (this == &a || this == &b)
699                 throw "BigUnsigned::bitOr: One of the arguments is the invoked object";
700         BlkNum i;
701         Blk *blkI;
702         const BigUnsigned *a2, *b2;
703         if (a.len >= b.len) {
704                 a2 = &a;
705                 b2 = &b;
706         } else {
707                 a2 = &b;
708                 b2 = &a;
709         }
710         allocate(a2->len);
711         const Blk *a2BlkI, *b2BlkI;
712         for (i = 0, blkI = blk, a2BlkI = a2->blk, b2BlkI = b2->blk;
713         i < b2->len; i++, blkI++, a2BlkI++, b2BlkI++)
714     *blkI = *a2BlkI | *b2BlkI;
715         for (; i < a2->len; i++, blkI++, a2BlkI++)
716                 *blkI = *a2BlkI;
717         len = a2->len;
718 }
719
720 // Bitwise xor
721 void BigUnsigned::bitXor(const BigUnsigned &a, const BigUnsigned &b) {
722         // Block unsafe calls
723         if (this == &a || this == &b)
724                 throw "BigUnsigned::bitXor: One of the arguments is the invoked object";
725         BlkNum i;
726         Blk *blkI;
727         const BigUnsigned *a2, *b2;
728         if (a.len >= b.len) {
729                 a2 = &a;
730                 b2 = &b;
731         } else {
732                 a2 = &b;
733                 b2 = &a;
734         }
735         allocate(b2->len);
736         const Blk *a2BlkI, *b2BlkI;
737         for (i = 0, blkI = blk, a2BlkI = a2->blk, b2BlkI = b2->blk;
738         i < b2->len; i++, blkI++, a2BlkI++, b2BlkI++)
739     *blkI = *a2BlkI ^ *b2BlkI;
740         for (; i < a2->len; i++, blkI++, a2BlkI++)
741                 *blkI = *a2BlkI;
742         len = a2->len;
743         zapLeadingZeros();
744 }
745
746 // INCREMENT/DECREMENT OPERATORS
747
748 // Prefix increment
749 void BigUnsigned::operator ++() {
750         BlkNum i;
751         Blk *blkI;
752         bool carry = true;
753         for (i = 0, blkI = blk; i < len && carry; i++) {
754                 (*blkI)++;
755                 carry = (*blkI == 0);
756         }
757         if (carry) {
758                 allocateAndCopy(len + 1);
759                 *blkI = 1;
760         }
761 }
762
763 // Postfix increment: same as prefix
764 void BigUnsigned::operator ++(int) {
765         operator ++();
766 }
767
768 // Prefix decrement
769 void BigUnsigned::operator --() {
770         if (len == 0)
771                 throw "BigUnsigned::operator --(): Cannot decrement an unsigned zero";
772         BlkNum i;
773         Blk *blkI;
774         bool borrow = true;
775         for (i = 0, blkI = blk; borrow; i++) {
776                 borrow = (*blkI == 0);
777                 (*blkI)--;
778         }
779         if (blk[len - 1] == 0)
780                 len--;
781 }
782
783 // Postfix decrement: same as prefix
784 void BigUnsigned::operator --(int) {
785         operator --();
786 }
787