Old snapshot `BigIntegerLibrary-2005.01.06'; see the ChangeLog file.
[bigint/bigint.git] / BigInteger.cc
CommitLineData
e67d6049
MM
1/*
2* Matt McCutchen's Big Integer Library
05780f4b 3* http://mysite.verizon.net/mccutchen/bigint/
e67d6049
MM
4*/
5
05780f4b 6#include "BigInteger.hh"
e67d6049
MM
7
8// MANAGEMENT
9
10// Assignment operator
11void BigInteger::operator =(const BigInteger &x) {
12 // Calls like a = a have no effect
13 if (this == &x)
14 return;
15 // Copy sign
16 sign = x.sign;
17 // Copy the rest
18 BigUnsigned::operator =(x);
19}
20
21// Constructor from an array of blocks and a sign
05780f4b 22BigInteger::BigInteger(const Blk *b, Index l, Sign s) : BigUnsigned(b, l) {
e67d6049
MM
23 switch (s) {
24 case zero:
25 case positive:
26 case negative:
27 sign = (len == 0) ? zero : s;
28 break;
29 default:
05780f4b 30 throw "BigInteger::BigInteger(Blk *, Index, Sign): Invalid sign";
e67d6049
MM
31 }
32}
33
34// Constructor from a BigUnsigned and a sign
35BigInteger::BigInteger(const BigUnsigned &x, Sign s) : BigUnsigned(x) {
36 switch (s) {
37 case zero:
38 case positive:
39 case negative:
40 sign = (len == 0) ? zero : s;
41 break;
42 default:
05780f4b 43 throw "BigInteger::BigInteger(Blk *, Index, Sign): Invalid sign";
e67d6049
MM
44 }
45}
46
47/*
48* The steps for construction of a BigInteger
49* from an integral value x are as follows:
50* 1. If x is zero, create an empty BigInteger and stop.
51* 2. Allocate a one-block number array.
52* 3. If x is positive (or of an unsigned type), set the
53* sign of the BigInteger to positive.
54* 4. If x is of a signed type and is negative, set the
55* sign of the BigInteger to negative.
56* 5. If x is of a signed type, convert x (or -x if x < 0)
57* to the unsigned type of the same length.
58* 6. Expand x (or the result of step 5) to a Blk,
59* and store it in the number array.
b3fe29df
MM
60*
61* See remarks in `BigUnsigned.cc' and `NumberlikeArray.hh'
62* about new handling of zero-length arrays.
e67d6049
MM
63*/
64
65BigInteger::BigInteger(unsigned long x) {
b3fe29df
MM
66 if (x == 0)
67 sign = zero; // NumberlikeArray did the rest
68 else {
e67d6049
MM
69 cap = 1;
70 blk = new Blk[1];
71 sign = positive;
72 len = 1;
73 *blk = Blk(x);
74 }
75}
76
77BigInteger::BigInteger(long x) {
78 if (x > 0) {
79 cap = 1;
80 blk = new Blk[1];
81 sign = positive;
82 len = 1;
83 *blk = Blk(x);
84 } else if (x < 0) {
85 cap = 1;
86 blk = new Blk[1];
87 sign = negative;
88 len = 1;
89 *blk = Blk(-x);
b3fe29df
MM
90 } else
91 sign = zero;
e67d6049
MM
92}
93
94BigInteger::BigInteger(unsigned int x) {
b3fe29df 95 if (x == 0)
e67d6049 96 sign = zero;
b3fe29df 97 else {
e67d6049
MM
98 cap = 1;
99 blk = new Blk[1];
100 sign = positive;
101 len = 1;
102 *blk = Blk(x);
103 }
104}
105
106BigInteger::BigInteger(int x) {
107 if (x > 0) {
108 cap = 1;
109 blk = new Blk[1];
110 sign = positive;
111 len = 1;
112 *blk = Blk(x);
113 } else if (x < 0) {
114 cap = 1;
115 blk = new Blk[1];
116 sign = negative;
117 len = 1;
118 *blk = Blk(-x);
b3fe29df
MM
119 } else
120 sign = zero;
e67d6049
MM
121}
122
123BigInteger::BigInteger(unsigned short x) {
b3fe29df 124 if (x == 0)
e67d6049 125 sign = zero;
b3fe29df 126 else {
e67d6049
MM
127 cap = 1;
128 blk = new Blk[1];
129 sign = positive;
130 len = 1;
131 *blk = Blk(x);
132 }
133}
134
135BigInteger::BigInteger(short x) {
136 if (x > 0) {
137 cap = 1;
138 blk = new Blk[1];
139 sign = positive;
140 len = 1;
141 *blk = Blk(x);
142 } else if (x < 0) {
143 cap = 1;
144 blk = new Blk[1];
145 sign = negative;
146 len = 1;
147 *blk = Blk(-x);
b3fe29df
MM
148 } else
149 sign = zero;
e67d6049
MM
150}
151
152// CONVERTERS
153/*
154* The steps for conversion of a BigInteger to an
155* integral type are as follows:
156* 1. If the BigInteger is zero, return zero.
157* 2. If the BigInteger is positive:
158* 3. If it is more than one block long or its lowest
159* block has bits set out of the range of the target
160* type, throw an exception.
161* 4. Otherwise, convert the lowest block to the
162* target type and return it.
163* 5. If the BigInteger is negative:
164* 6. If the target type is unsigned, throw an exception.
165* 7. If it is more than one block long or its lowest
166* block has bits set out of the range of the target
167* type, throw an exception.
168* 8. Otherwise, convert the lowest block to the
169* target type, negate it, and return it.
170*/
171
172namespace {
173 // These masks are used to test whether a Blk has bits
174 // set out of the range of a smaller integral type. Note
175 // that this range is not considered to include the sign bit.
176 const BigUnsigned::Blk lMask = ~0 >> 1;
177 const BigUnsigned::Blk uiMask = (unsigned int)(~0);
178 const BigUnsigned::Blk iMask = uiMask >> 1;
179 const BigUnsigned::Blk usMask = (unsigned short)(~0);
180 const BigUnsigned::Blk sMask = usMask >> 1;
181}
182
183BigInteger::operator unsigned long() const {
184 switch (sign) {
185 case zero:
186 return 0;
187 case positive:
188 if (len == 1)
189 return *blk;
190 else
191 throw "BigInteger operator unsigned long() const: Value is too big for an unsigned long";
192 case negative:
193 throw "BigInteger operator unsigned long() const: Cannot convert a negative integer to an unsigned type";
194 default:
195 throw "BigInteger: Internal error";
196 }
197}
198
199BigInteger::operator long() const {
200 switch (sign) {
201 case zero:
202 return 0;
203 case positive:
204 if (len == 1 && (*blk & ~lMask) == 0)
205 return long(*blk);
206 else
207 throw "BigInteger operator long() const: Value is too big for a long";
208 case negative:
209 if (len == 1 && (*blk & ~lMask) == 0)
210 return -long(*blk);
211 else
212 throw "BigInteger operator long() const: Value is too big for a long";
213 default:
214 throw "BigInteger: Internal error";
215 }
216}
217
218BigInteger::operator unsigned int() const {
219 switch (sign) {
220 case zero:
221 return 0;
222 case positive:
223 if (len == 1 && (*blk & ~uiMask) == 0)
224 return (unsigned int)(*blk);
225 else
226 throw "BigInteger operator unsigned int() const: Value is too big for an unsigned int";
227 case negative:
228 throw "BigInteger operator unsigned int() const: Cannot convert a negative integer to an unsigned type";
229 default:
230 throw "BigInteger: Internal error";
231 }
232}
233
234BigInteger::operator int() const {
235 switch (sign) {
236 case zero:
237 return 0;
238 case positive:
239 if (len == 1 && (*blk & ~iMask) == 0)
240 return int(*blk);
241 else
242 throw "BigInteger operator int() const: Value is too big for an int";
243 case negative:
244 if (len == 1 && (*blk & ~iMask) == 0)
245 return -int(*blk);
246 else
247 throw "BigInteger operator int() const: Value is too big for an int";
248 default:
249 throw "BigInteger: Internal error";
250 }
251}
252
253BigInteger::operator unsigned short() const {
254 switch (sign) {
255 case zero:
256 return 0;
257 case positive:
258 if (len == 1 && (*blk & ~usMask) == 0)
259 return (unsigned short)(*blk);
260 else
261 throw "BigInteger operator unsigned short() const: Value is too big for an unsigned short";
262 case negative:
263 throw "BigInteger operator unsigned short() const: Cannot convert a negative integer to an unsigned type";
264 default:
265 throw "BigInteger: Internal error";
266 }
267}
268
269BigInteger::operator short() const {
270 switch (sign) {
271 case zero:
272 return 0;
273 case positive:
274 if (len == 1 && (*blk & ~sMask) == 0)
275 return short(*blk);
276 else
277 throw "BigInteger operator short() const: Value is too big for a short";
278 case negative:
279 if (len == 1 && (*blk & ~sMask) == 0)
280 return -short(*blk);
281 else
282 throw "BigInteger operator short() const: Value is too big for a short";
283 default:
284 throw "BigInteger: Internal error";
285 }
286}
287
288// COMPARISON
289BigInteger::CmpRes BigInteger::compareTo(const BigInteger &x) const {
290 // A greater sign implies a greater number
291 if (sign < x.sign)
292 return less;
293 else if (sign > x.sign)
294 return greater;
295 else switch (sign) {
296 // If the signs are the same...
297 case zero:
298 return equal; // Two zeros are equal
299 case positive:
300 // Compare the magnitudes
301 return BigUnsigned::compareTo(x);
302 case negative:
303 // Compare the magnitudes, but return the opposite result
304 return CmpRes(-BigUnsigned::compareTo(x));
305 default:
306 throw "BigInteger: Internal error";
307 }
308}
309
310// PUT-HERE OPERATIONS
311// These do some messing around to determine the sign of the result,
312// then call one of BigUnsigned's put-heres.
313
314// Addition
315void BigInteger::add(const BigInteger &a, const BigInteger &b) {
316 // Block unsafe calls
317 if (this == &a || this == &b)
318 throw "BigInteger::add: One of the arguments is the invoked object";
319 // If one argument is zero, copy the other.
320 if (a.sign == zero)
321 operator =(b);
322 else if (b.sign == zero)
323 operator =(a);
324 // If the arguments have the same sign, take the
325 // common sign and add their magnitudes.
326 else if (a.sign == b.sign) {
327 sign = a.sign;
328 BigUnsigned::add(a, b);
329 } else {
330 // Otherwise, their magnitudes must be compared.
331 switch (a.BigUnsigned::compareTo(b)) {
332 // If their magnitudes are the same, copy zero.
333 case equal:
334 len = 0;
335 sign = zero;
336 break;
337 // Otherwise, take the sign of the greater, and subtract
338 // the lesser magnitude from the greater magnitude.
339 case greater:
340 sign = a.sign;
341 BigUnsigned::subtract(a, b);
342 break;
343 case less:
344 sign = b.sign;
345 BigUnsigned::subtract(b, a);
346 break;
347 }
348 }
349}
350
351// Subtraction
352void BigInteger::subtract(const BigInteger &a, const BigInteger &b) {
353 // Notice that this routine is identical to BigInteger::add,
354 // if one replaces b.sign by its opposite.
355 // Block unsafe calls
356 if (this == &a || this == &b)
357 throw "BigInteger::subtract: One of the arguments is the invoked object";
358 // If a is zero, copy b and flip its sign. If b is zero, copy a.
359 if (a.sign == zero) {
360 BigUnsigned::operator =(b);
361 sign = Sign(-sign);
362 } else if (b.sign == zero)
363 operator =(a);
364 // If their signs differ, take a.sign and add the magnitudes.
365 else if (a.sign != b.sign) {
366 sign = a.sign;
367 BigUnsigned::add(a, b);
368 } else {
369 // Otherwise, their magnitudes must be compared.
370 switch (a.BigUnsigned::compareTo(b)) {
371 // If their magnitudes are the same, copy zero.
372 case equal:
373 len = 0;
374 sign = zero;
375 break;
376 // If a's magnitude is greater, take a.sign and
377 // subtract a from b.
378 case greater:
379 sign = a.sign;
380 BigUnsigned::subtract(a, b);
381 break;
382 // If b's magnitude is greater, take the opposite
383 // of b.sign and subtract b from a.
384 case less:
385 sign = Sign(-b.sign);
386 BigUnsigned::subtract(b, a);
387 break;
388 }
389 }
390}
391
392// Multiplication
393void BigInteger::multiply(const BigInteger &a, const BigInteger &b) {
394 // Block unsafe calls
395 if (this == &a || this == &b)
396 throw "BigInteger::multiply: One of the arguments is the invoked object";
397 // If one object is zero, copy zero and return.
398 if (a.sign == zero || b.sign == zero) {
399 sign = zero;
400 len = 0;
401 return;
402 }
403 // If the signs of the arguments are the same, the result
404 // is positive, otherwise it is negative.
405 sign = (a.sign == b.sign) ? positive : negative;
406 // Multiply the magnitudes.
407 BigUnsigned::multiply(a, b);
408}
409
05780f4b
MM
410/*
411* DIVISION WITH REMAINDER
412* Please read the comments before the definition of
413* `BigUnsigned::divideWithRemainder' in `BigUnsigned.cc' for lots of
414* information you should know before reading this function.
415*
416* Following Knuth, I decree that x / y is to be
417* 0 if y==0 and floor(real-number x / y) if y!=0.
418* Then x % y shall be x - y*(integer x / y).
419*
420* Note that x = y * (x / y) + (x % y) always holds.
421* In addition, (x % y) is from 0 to y - 1 if y > 0,
422* and from -(|y| - 1) to 0 if y < 0. (x % y) = x if y = 0.
423*
424* Examples: (q = a / b, r = a % b)
425* a b q r
426* === === === ===
427* 4 3 1 1
428* -4 3 -2 2
429* 4 -3 -2 -2
430* -4 -3 1 -1
431*/
432void BigInteger::divideWithRemainder(const BigInteger &b, BigInteger &q) {
e67d6049 433 // Block unsafe calls
05780f4b
MM
434 if (this == &b || this == &q || &b == &q)
435 throw "BigInteger::divideWithRemainder: One of the arguments is the invoked object";
436 // Division by zero gives quotient 0 and remainder *this
437 if (b.sign == zero) {
438 q.len = 0;
439 q.sign = zero;
e67d6049
MM
440 return;
441 }
05780f4b
MM
442 // 0 / b gives quotient 0 and remainder 0
443 if (sign == zero) {
444 q.len = 0;
445 q.sign = zero;
e67d6049
MM
446 return;
447 }
05780f4b
MM
448
449 // Here *this != 0, b != 0.
450
451 // Do the operands have the same sign?
452 if (sign == b.sign) {
453 // Yes: easy case. Quotient is zero or positive.
454 q.sign = positive;
455 } else {
456 // No: harder case. Quotient is negative.
457 q.sign = negative;
458 // Decrease the magnitude of the dividend by one.
459 BigUnsigned::operator --();
460 /*
461 * We tinker with the dividend before and with the
462 * quotient and remainder after so that the result
463 * comes out right. To see why it works, consider the following
464 * list of examples, where A is the magnitude-decreased
465 * a, Q and R are the results of BigUnsigned division
466 * with remainder on A and |b|, and q and r are the
467 * final results we want:
468 *
469 * a A b Q R q r
470 * -3 -2 3 0 2 -1 0
471 * -4 -3 3 1 0 -2 2
472 * -5 -4 3 1 1 -2 1
473 * -6 -5 3 1 2 -2 0
474 *
475 * It appears that we need a total of 3 corrections:
476 * Decrease the magnitude of a to get A. Increase the
477 * magnitude of Q to get q (and make it negative).
478 * Find r = (b - 1) - R and give it the desired sign.
479 */
480 }
481
482 // Divide the magnitudes.
483 BigUnsigned::divideWithRemainder(b, q);
484
485 if (sign != b.sign) {
486 // More for the harder case (as described):
487 // Increase the magnitude of the quotient by one.
488 q.BigUnsigned::operator ++();
489 // Modify the remainder.
490 BigUnsigned temp(*this);
491 BigUnsigned::subtract(b, temp);
492 BigUnsigned::operator --();
493 }
494
495 // Sign of the remainder is always the sign of the divisor b.
496 sign = b.sign;
497
498 // Set signs to zero as necessary. (Thanks David Allen!)
e67d6049
MM
499 if (len == 0)
500 sign = zero;
05780f4b
MM
501 if (q.len == 0)
502 q.sign = zero;
503
504 // WHEW!!!
e67d6049
MM
505}
506
507// Negation
508void BigInteger::negate(const BigInteger &a) {
509 // Block unsafe calls
510 if (this == &a)
511 throw "BigInteger::negate: The argument is the invoked object";
512 // Copy a's magnitude
513 BigUnsigned::operator =(a);
514 // Copy the opposite of a.sign
515 sign = Sign(-a.sign);
516}
517
518// INCREMENT/DECREMENT OPERATORS
519
520// Prefix increment
521void BigInteger::operator ++() {
522 switch (sign) {
523 case zero:
524 allocate(1);
525 sign = positive;
526 len = 1;
527 *blk = 1;
528 break;
529 case positive:
530 BigUnsigned::operator ++();
531 break;
532 case negative:
533 BigUnsigned::operator --();
534 if (len == 0)
535 sign = zero;
536 break;
537 }
538}
539
540// Postfix increment: same as prefix
541void BigInteger::operator ++(int) {
542 operator ++();
543}
544
545// Prefix decrement
546void BigInteger::operator --() {
547 switch (sign) {
548 case zero:
549 allocate(1);
550 sign = negative;
551 len = 1;
552 *blk = 1;
553 break;
554 case negative:
555 BigUnsigned::operator ++();
556 break;
557 case positive:
558 BigUnsigned::operator --();
559 if (len == 0)
560 sign = zero;
561 break;
562 }
563}
564
565// Postfix decrement: same as prefix
566void BigInteger::operator --(int) {
567 operator --();
568}
569