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