Indent comments an extra space so the stars line up.
[bigint/bigint.git] / BigUnsigned.hh
1 /*
2  * Matt McCutchen's Big Integer Library
3  */
4
5 #ifndef BIGUNSIGNED
6 #define BIGUNSIGNED
7
8 #include "NumberlikeArray.hh"
9
10 /*
11  * A BigUnsigned object represents a nonnegative integer of size
12  * limited only by available memory.  A BigUnsigned can be
13  * created from and converted back to most integral types,
14  * and many math operations are defined on BigUnsigneds.
15  *
16  * The number is stored as a series of blocks in a
17  * dynamically allocated array.  It is as if the number
18  * were written digit by digit in base 2 ^ N, **where N is the
19  * number of bits in an unsigned long.**
20  *
21  * The memory-management details that used to be in here have
22  * been moved into NumberlikeArray, which BigUnsigned now derives from.
23  * `(NlA)' means that member(s) are declared identically in NumberlikeArray.
24  * Such members are either redeclared here to make them public or are
25  * here, commented out, for reference.
26  */
27
28 class BigUnsigned : protected NumberlikeArray<unsigned long> {
29
30         // TYPES & CONSTANTS
31         public:
32         enum CmpRes { less = -1, equal = 0, greater = 1 }; // Enumeration for the result of a comparison
33         typedef unsigned long Blk; // The number block type that BigUnsigneds are built from
34         typedef NumberlikeArray<Blk>::Index Index; // (NlA) Type for the index of a block in the array
35         NumberlikeArray<Blk>::N; // Number of bits in a Blk
36
37         /*
38         // FIELDS
39         protected:
40         Index cap; // (NlA) The current allocated capacity of this BigUnsigned (in blocks)
41         Index len; // (NlA) The actual length of the number stored in this BigUnsigned (in blocks)
42         Blk *blk; // (NlA) Dynamically allocated array of the number blocks
43         */
44
45         // MANAGEMENT
46         protected:
47         // These members generally defer to those in NumberlikeArray, possibly with slight changes.
48         // It might be nice if one could request that constructors be inherited in C++.
49
50         BigUnsigned(int, Index c) : NumberlikeArray<Blk>(0, c) {} // Creates a BigUnsigned with a capacity
51
52         void zapLeadingZeros() { // Decreases len to eliminate leading zeros
53                 while (len > 0 && blk[len - 1] == 0)
54                         len--;
55         }
56
57         //void allocate(Index c); // (NlA) Ensures the number array has at least the indicated capacity, maybe discarding contents
58         //void allocateAndCopy(Index c); // (NlA) Ensures the number array has at least the indicated capacity, preserving its contents
59
60         public:
61         BigUnsigned() : NumberlikeArray<Blk>() {} // Default constructor (value is 0)
62         BigUnsigned(const BigUnsigned &x) : NumberlikeArray<Blk>(x) {} // Copy constructor
63
64         void operator=(const BigUnsigned &x) { // Assignment operator
65                 NumberlikeArray<Blk>::operator =(x);
66         }
67
68         BigUnsigned(const Blk *b, Index l) : NumberlikeArray<Blk>(b, l) { // Constructor from an array of blocks
69                 zapLeadingZeros();
70         }
71
72         // Constructors from integral types
73         BigUnsigned(unsigned long  x);
74         BigUnsigned(         long  x);
75         BigUnsigned(unsigned int   x);
76         BigUnsigned(         int   x);
77         BigUnsigned(unsigned short x);
78         BigUnsigned(         short x);
79         ~BigUnsigned() {} // Destructor
80
81         // CONVERTERS to integral types
82         public:
83         operator unsigned long () const;
84         operator          long () const;
85         operator unsigned int  () const;
86         operator          int  () const;
87         operator unsigned short() const;
88         operator          short() const;
89
90         // PICKING APART
91         // These accessors can be used to get the pieces of the number
92         public:
93         NumberlikeArray<Blk>::getCapacity;
94         NumberlikeArray<Blk>::getLength;
95         // Note that getBlock returns 0 if the block index is beyond the length of the number.
96         // A routine that uses this accessor can safely assume a BigUnsigned has 0s infinitely to the left.
97         Blk getBlock(Index i) const { return i >= len ? 0 : blk[i]; }
98         // Note how we replace one level of abstraction with another.  Isn't that neat?
99         bool isZero() const { return NumberlikeArray<Blk>::isEmpty(); } // Often convenient for loops
100
101         // COMPARISONS
102         public:
103         // Compares this to x like Perl's <=>
104         CmpRes compareTo(const BigUnsigned &x) const;
105         // Normal comparison operators
106         // Bug fixed 2006.04.24: Only we, not the user, can pass a BigUnsigned off as a
107         // NumberlikeArray, so we have to wrap == and !=.
108         bool operator ==(const BigUnsigned &x) const {
109                 return NumberlikeArray<Blk>::operator ==(x);
110         }
111         bool operator !=(const BigUnsigned &x) const {
112                 return NumberlikeArray<Blk>::operator !=(x);
113         }
114         bool operator < (const BigUnsigned &x) const { return compareTo(x) == less   ; }
115         bool operator <=(const BigUnsigned &x) const { return compareTo(x) != greater; }
116         bool operator >=(const BigUnsigned &x) const { return compareTo(x) != less   ; }
117         bool operator > (const BigUnsigned &x) const { return compareTo(x) == greater; }
118
119         /*
120          * BigUnsigned and BigInteger both provide three kinds of operators.
121          * Here ``big-integer'' refers to BigInteger or BigUnsigned.
122          *
123          * (1) Overloaded ``return-by-value'' operators:
124          *     +, -, *, /, %, unary -.
125          * Big-integer code using these operators looks identical to
126          * code using the primitive integer types.  These operators take
127          * one or two big-integer inputs and return a big-integer result,
128          * which can then be assigned to a BigInteger variable or used
129          * in an expression.  Example:
130          *     BigInteger a(1), b = 1;
131          *     BigInteger c = a + b;
132          *
133          * (2) Overloaded assignment operators:
134          *     +=, -=, *=, /=, %=, &=, |=, ^=, ++, --, flipSign.
135          * Again, these are used on big integers just like on ints.
136          * They take one writable big integer that both provides an
137          * operand and receives a result.  The first eight also take
138          * a second read-only operand.  Example:
139          *     BigInteger a(1), b(1);
140          *     a += b;
141          *
142          * (3) ``Put-here'' operations: `add', `subtract', etc.
143          * Using a return-by-value or assignment operator generally involves
144          * copy constructions and/or assignments.  The ``put-here'' operations
145          * require none, but they are more of a hassle to use.  Most take two
146          * read-only operands and save the result in the calling object `*this',
147          * whose previous value is ignored.  `divideWithRemainder' is an exception.
148          * <<< NOTE >>>: Put-here operations do not return a value: they don't need to!!
149          * Examples:
150          *     BigInteger a(43), b(7), c, d;
151          *     c = a + b;   // Now c == 50.
152          *     c.add(a, b); // Same effect but without the two bulk-copies.
153          *     c.divideWithRemainder(b, d); // 50 / 7; now d == 7 (quotient) and c == 1 (remainder).
154          *     a.add(a, b); // ``Aliased'' calls now do the right thing using a
155          *              // temporary copy, but see note on divideWithRemainder.
156          */
157
158         // PUT-HERE OPERATIONS
159         public:
160         /* These 3: Two read-only operands as arguments.  Result left in *this. */
161         void add(const BigUnsigned &a, const BigUnsigned &b); // Addition
162         void subtract(const BigUnsigned &a, const BigUnsigned &b); // Subtraction
163         void multiply(const BigUnsigned &a, const BigUnsigned &b); // Multiplication
164         /* Divisive stuff
165          * `a.divideWithRemainder(b, q)' is like `q = a / b, a %= b'.
166          * Semantics similar to Donald E. Knuth's are used for / and %,
167          * and these differ from the semantics of primitive-type
168          * / and % under division by zero.
169          * Look in `BigUnsigned.cc' for details.
170          * `a.divideWithRemainder(b, a)' causes an exception: it doesn't make
171          * sense to write quotient and remainder into the same variable.
172          */
173         void divideWithRemainder(const BigUnsigned &b, BigUnsigned &q);
174         void divide(const BigUnsigned &a, const BigUnsigned &b) {
175                 BigUnsigned a2(a);
176                 a2.divideWithRemainder(b, *this);
177                 // quotient now in *this
178                 // don't care about remainder left in a2
179         }
180         void modulo(const BigUnsigned &a, const BigUnsigned &b) {
181                 *this = a;
182                 BigUnsigned q;
183                 divideWithRemainder(b, q);
184                 // remainder now in *this
185                 // don't care about quotient left in q
186         }
187         // Bitwise operations.  Result left in *this.
188         // These are not provided for BigIntegers; I think that using them on BigIntegers
189         // will discard the sign first.
190         void bitAnd(const BigUnsigned &a, const BigUnsigned &b); // Bitwise AND
191         void bitOr(const BigUnsigned &a, const BigUnsigned &b); // Bitwise OR
192         void bitXor(const BigUnsigned &a, const BigUnsigned &b); // Bitwise XOR
193         void bitShiftLeft(const BigUnsigned &a, unsigned int b); // Bitwise left shift
194         void bitShiftRight(const BigUnsigned &a, unsigned int b); // Bitwise right shift
195
196         // NORMAL OPERATORS
197         // These perform the operation on this (to the left of the operator)
198         // and x (to the right of the operator) and return a new BigUnsigned with the result.
199         public:
200         BigUnsigned operator +(const BigUnsigned &x) const; // Addition
201         BigUnsigned operator -(const BigUnsigned &x) const; // Subtraction
202         BigUnsigned operator *(const BigUnsigned &x) const; // Multiplication
203         BigUnsigned operator /(const BigUnsigned &x) const; // Division
204         BigUnsigned operator %(const BigUnsigned &x) const; // Modular reduction
205         BigUnsigned operator &(const BigUnsigned &x) const; // Bitwise AND
206         BigUnsigned operator |(const BigUnsigned &x) const; // Bitwise OR
207         BigUnsigned operator ^(const BigUnsigned &x) const; // Bitwise XOR
208         BigUnsigned operator <<(unsigned int b) const; // Bitwise left shift
209         BigUnsigned operator >>(unsigned int b) const; // Bitwise right shift
210         // Additional operators in an attempt to avoid overloading tangles.
211         BigUnsigned operator <<(int b) const;
212         BigUnsigned operator >>(int b) const;
213
214         // ASSIGNMENT OPERATORS
215         // These perform the operation on this and x, storing the result into this.
216         public:
217         void operator +=(const BigUnsigned &x); // Addition
218         void operator -=(const BigUnsigned &x); // Subtraction
219         void operator *=(const BigUnsigned &x); // Multiplication
220         void operator /=(const BigUnsigned &x); // Division
221         void operator %=(const BigUnsigned &x); // Modular reduction
222         void operator &=(const BigUnsigned &x); // Bitwise AND
223         void operator |=(const BigUnsigned &x); // Bitwise OR
224         void operator ^=(const BigUnsigned &x); // Bitwise XOR
225         void operator <<=(unsigned int b); // Bitwise left shift
226         void operator >>=(unsigned int b); // Bitwise right shift
227         // Additional operators in an attempt to avoid overloading tangles.
228         void operator <<=(int b);
229         void operator >>=(int b);
230
231         // INCREMENT/DECREMENT OPERATORS
232         // These increase or decrease the number by 1.  To discourage side effects,
233         // these do not return *this, so prefix and postfix behave the same.
234         public:
235         void operator ++(   ); // Prefix  increment
236         void operator ++(int); // Postfix decrement
237         void operator --(   ); // Prefix  increment
238         void operator --(int); // Postfix decrement
239
240         // Helper function that needs access to BigUnsigned internals
241         friend Blk getShiftedBlock(const BigUnsigned &num, Index x, unsigned int y);
242 };
243
244 // NORMAL OPERATORS
245 /* These create an object to hold the result and invoke
246  * the appropriate put-here operation on it, passing
247  * this and x.  The new object is then returned. */
248 inline BigUnsigned BigUnsigned::operator +(const BigUnsigned &x) const {
249         BigUnsigned ans;
250         ans.add(*this, x);
251         return ans;
252 }
253 inline BigUnsigned BigUnsigned::operator -(const BigUnsigned &x) const {
254         BigUnsigned ans;
255         ans.subtract(*this, x);
256         return ans;
257 }
258 inline BigUnsigned BigUnsigned::operator *(const BigUnsigned &x) const {
259         BigUnsigned ans;
260         ans.multiply(*this, x);
261         return ans;
262 }
263 inline BigUnsigned BigUnsigned::operator /(const BigUnsigned &x) const {
264         BigUnsigned ans;
265         ans.divide(*this, x);
266         return ans;
267 }
268 inline BigUnsigned BigUnsigned::operator %(const BigUnsigned &x) const {
269         BigUnsigned ans;
270         ans.modulo(*this, x);
271         return ans;
272 }
273 inline BigUnsigned BigUnsigned::operator &(const BigUnsigned &x) const {
274         BigUnsigned ans;
275         ans.bitAnd(*this, x);
276         return ans;
277 }
278 inline BigUnsigned BigUnsigned::operator |(const BigUnsigned &x) const {
279         BigUnsigned ans;
280         ans.bitOr(*this, x);
281         return ans;
282 }
283 inline BigUnsigned BigUnsigned::operator ^(const BigUnsigned &x) const {
284         BigUnsigned ans;
285         ans.bitXor(*this, x);
286         return ans;
287 }
288 inline BigUnsigned BigUnsigned::operator <<(unsigned int b) const {
289         BigUnsigned ans;
290         ans.bitShiftLeft(*this, b);
291         return ans;
292 }
293 inline BigUnsigned BigUnsigned::operator >>(unsigned int b) const {
294         BigUnsigned ans;
295         ans.bitShiftRight(*this, b);
296         return ans;
297 }
298 inline BigUnsigned BigUnsigned::operator <<(int b) const {
299         if (b < 0)
300                 throw "BigUnsigned::operator <<(int): Negative shift amounts are not supported";
301         return *this << (unsigned int)(b);
302 }
303 inline BigUnsigned BigUnsigned::operator >>(int b) const {
304         if (b < 0)
305                 throw "BigUnsigned::operator >>(int): Negative shift amounts are not supported";
306         return *this >> (unsigned int)(b);
307 }
308
309 /*
310  * ASSIGNMENT OPERATORS
311  * 
312  * Now the responsibility for making a temporary copy if necessary
313  * belongs to the put-here operations.  I made this change on 2007.02.13 after
314  * Boris Dessy pointed out that the old implementation handled calls like
315  * "a *= a" badly: it translated them to essentially "a.multiply(aCopy, a)",
316  * which threw an exception.
317  */
318 inline void BigUnsigned::operator +=(const BigUnsigned &x) {
319         add(*this, x);
320 }
321 inline void BigUnsigned::operator -=(const BigUnsigned &x) {
322         subtract(*this, x);
323 }
324 inline void BigUnsigned::operator *=(const BigUnsigned &x) {
325         multiply(*this, x);
326 }
327 inline void BigUnsigned::operator /=(const BigUnsigned &x) {
328         // Updated for divideWithRemainder
329         BigUnsigned thisCopy(*this);
330         thisCopy.divideWithRemainder(x, *this);
331         // quotient left in *this
332         // don't care about remainder left in thisCopy
333 }
334 inline void BigUnsigned::operator %=(const BigUnsigned &x) {
335         // Shortcut (woohoo!)
336         BigUnsigned q;
337         divideWithRemainder(x, q);
338         // remainder left in *this
339         // don't care about quotient left in q
340 }
341 inline void BigUnsigned::operator &=(const BigUnsigned &x) {
342         bitAnd(*this, x);
343 }
344 inline void BigUnsigned::operator |=(const BigUnsigned &x) {
345         bitOr(*this, x);
346 }
347 inline void BigUnsigned::operator ^=(const BigUnsigned &x) {
348         bitXor(*this, x);
349 }
350 inline void BigUnsigned::operator <<=(unsigned int b) {
351         bitShiftLeft(*this, b);
352 }
353 inline void BigUnsigned::operator >>=(unsigned int b) {
354         bitShiftRight(*this, b);
355 }
356 inline void BigUnsigned::operator <<=(int b) {
357         if (b < 0)
358                 throw "BigUnsigned::operator <<=(int): Negative shift amounts are not supported";
359         *this <<= (unsigned int)(b);
360 }
361 inline void BigUnsigned::operator >>=(int b) {
362         if (b < 0)
363                 throw "BigUnsigned::operator >>=(int): Negative shift amounts are not supported";
364         *this >>= (unsigned int)(b);
365 }
366
367 #endif