Old snapshot `bigint-2006.02.26'; 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         NumberlikeArray<Blk>::operator ==; // (NlA) The body used to be `{ return compareTo(x) == equal; }'.  For performance reasons we use NumberlikeArray code that only worries about (in)equality and doesn't waste time determining which is bigger
108         NumberlikeArray<Blk>::operator !=; // (NlA) Ditto.
109         bool operator < (const BigUnsigned &x) const { return compareTo(x) == less   ; }
110         bool operator <=(const BigUnsigned &x) const { return compareTo(x) != greater; }
111         bool operator >=(const BigUnsigned &x) const { return compareTo(x) != less   ; }
112         bool operator > (const BigUnsigned &x) const { return compareTo(x) == greater; }
113
114         /*
115         * BigUnsigned and BigInteger both provide three kinds of operators.
116         * Here ``big-integer'' refers to BigInteger or BigUnsigned.
117         *
118         * (1) Overloaded ``return-by-value'' operators:
119         *     +, -, *, /, %, unary -.
120         * Big-integer code using these operators looks identical to
121         * code using the primitive integer types.  These operators take
122         * one or two big-integer inputs and return a big-integer result,
123         * which can then be assigned to a BigInteger variable or used
124         * in an expression.  Example:
125         *     BigInteger a(1), b = 1;
126         *     BigInteger c = a + b;
127         *
128         * (2) Overloaded assignment operators:
129         *     +=, -=, *=, /=, %=, &=, |=, ^=, ++, --, flipSign.
130         * Again, these are used on big integers just like on ints.
131         * They take one writable big integer that both provides an
132         * operand and receives a result.  The first eight also take
133         * a second read-only operand.  Example:
134         *     BigInteger a(1), b(1);
135         *     a += b;
136         *
137         * (3) ``Put-here'' operations: `add', `subtract', etc.
138         * Using a return-by-value or assignment operator generally involves
139         * copy constructions and/or assignments.  The ``put-here'' operations
140         * require none, but they are more of a hassle to use.  Most take two
141         * read-only operands and save the result in the calling object `*this',
142         * whose previous value is ignored.  `divideWithRemainder' is an exception.
143         * <<< NOTE >>>: Put-here operations do not return a value: they don't need to!!
144         * Examples:
145         *     BigInteger a(43), b(7), c, d;
146         *     c = a + b;   // Now c == 50.
147         *     c.add(a, b); // Same effect but without the two bulk-copies.
148         *     c.divideWithRemainder(b, d); // 50 / 7; now d == 7 (quotient) and c == 1 (remainder).
149         *     a.add(a, b); // Unsafe ``aliased'' call; causes a runtime error.
150         */
151         
152         // PUT-HERE OPERATIONS
153         public:
154         /* These 3: Two read-only operands as arguments.  Result left in *this. */
155         void add(const BigUnsigned &a, const BigUnsigned &b); // Addition
156         void subtract(const BigUnsigned &a, const BigUnsigned &b); // Subtraction
157         void multiply(const BigUnsigned &a, const BigUnsigned &b); // Multiplication
158         /* Divisive stuff
159         * `a.divideWithRemainder(b, q)' is like `q = a / b, a %= b'.
160         * Semantics similar to Donald E. Knuth's are used for / and %,
161         * and these differ from the semantics of primitive-type
162         * / and % under division by zero.
163         * Look in `BigUnsigned.cc' for details.
164         */
165         void divideWithRemainder(const BigUnsigned &b, BigUnsigned &q);
166         void divide(const BigUnsigned &a, const BigUnsigned &b) {
167                 // Division, deprecated and provided for backward compatibility
168                 BigUnsigned a2(a);
169                 a2.divideWithRemainder(b, *this);
170                 // quotient now in *this
171                 // don't care about remainder left in a2
172         }
173         void modulo(const BigUnsigned &a, const BigUnsigned &b) {
174                 // Modular reduction, deprecated and provided for backward compatibility
175                 *this = a;
176                 BigUnsigned q;
177                 divideWithRemainder(b, q);
178                 // remainder now in *this
179                 // don't care about quotient left in q
180         }
181         // Bitwise operations.  Two read-only operands as arguments.  Result left in *this.
182         // These are not provided for BigIntegers; I think that using them on BigIntegers
183         // will discard the sign first.
184         void bitAnd(const BigUnsigned &a, const BigUnsigned &b); // Bitwise AND
185         void bitOr(const BigUnsigned &a, const BigUnsigned &b); // Bitwise OR
186         void bitXor(const BigUnsigned &a, const BigUnsigned &b); // Bitwise XOR
187         
188         // These functions are declared but not defined.  (Sorry.)
189         // Trying to call either will result in a link-time error.
190         void bitShiftLeft(const BigUnsigned &a, unsigned int b); // Bitwise left shift
191         void bitShiftRight(const BigUnsigned &a, unsigned int b); // Bitwise right shift
192         
193         // NORMAL OPERATORS
194         // These perform the operation on this (to the left of the operator)
195         // and x (to the right of the operator) and return a new BigUnsigned with the result.
196         public:
197         BigUnsigned operator +(const BigUnsigned &x) const; // Addition
198         BigUnsigned operator -(const BigUnsigned &x) const; // Subtraction
199         BigUnsigned operator *(const BigUnsigned &x) const; // Multiplication
200         BigUnsigned operator /(const BigUnsigned &x) const; // Division
201         BigUnsigned operator %(const BigUnsigned &x) const; // Modular reduction
202         BigUnsigned operator &(const BigUnsigned &x) const; // Bitwise AND
203         BigUnsigned operator |(const BigUnsigned &x) const; // Bitwise OR
204         BigUnsigned operator ^(const BigUnsigned &x) const; // Bitwise XOR
205         
206         // ASSIGNMENT OPERATORS
207         // These perform the operation on this and x, storing the result into this.
208         public:
209         void operator +=(const BigUnsigned &x); // Addition
210         void operator -=(const BigUnsigned &x); // Subtraction
211         void operator *=(const BigUnsigned &x); // Multiplication
212         void operator /=(const BigUnsigned &x); // Division
213         void operator %=(const BigUnsigned &x); // Modular reduction
214         void operator &=(const BigUnsigned &x); // Bitwise AND
215         void operator |=(const BigUnsigned &x); // Bitwise OR
216         void operator ^=(const BigUnsigned &x); // Bitwise XOR
217         
218         // INCREMENT/DECREMENT OPERATORS
219         // These increase or decrease the number by 1.  To discourage side effects,
220         // these do not return *this, so prefix and postfix behave the same.
221         public:
222         void operator ++(   ); // Prefix  increment
223         void operator ++(int); // Postfix decrement
224         void operator --(   ); // Prefix  increment
225         void operator --(int); // Postfix decrement
226         
227         // Helper function that needs access to BigUnsigned internals
228         friend Blk getShiftedBlock(const BigUnsigned &num, Index x, unsigned int y);
229 };
230
231 // NORMAL OPERATORS
232 /* These create an object to hold the result and invoke
233 * the appropriate put-here operation on it, passing
234 * this and x.  The new object is then returned. */
235 inline BigUnsigned BigUnsigned::operator +(const BigUnsigned &x) const {
236         BigUnsigned ans;
237         ans.add(*this, x);
238         return ans;
239 }
240 inline BigUnsigned BigUnsigned::operator -(const BigUnsigned &x) const {
241         BigUnsigned ans;
242         ans.subtract(*this, x);
243         return ans;
244 }
245 inline BigUnsigned BigUnsigned::operator *(const BigUnsigned &x) const {
246         BigUnsigned ans;
247         ans.multiply(*this, x);
248         return ans;
249 }
250 inline BigUnsigned BigUnsigned::operator /(const BigUnsigned &x) const {
251         BigUnsigned ans;
252         ans.divide(*this, x);
253         return ans;
254 }
255 inline BigUnsigned BigUnsigned::operator %(const BigUnsigned &x) const {
256         BigUnsigned ans;
257         ans.modulo(*this, x);
258         return ans;
259 }
260 inline BigUnsigned BigUnsigned::operator &(const BigUnsigned &x) const {
261         BigUnsigned ans;
262         ans.bitAnd(*this, x);
263         return ans;
264 }
265 inline BigUnsigned BigUnsigned::operator |(const BigUnsigned &x) const {
266         BigUnsigned ans;
267         ans.bitOr(*this, x);
268         return ans;
269 }
270 inline BigUnsigned BigUnsigned::operator ^(const BigUnsigned &x) const {
271         BigUnsigned ans;
272         ans.bitXor(*this, x);
273         return ans;
274 }
275
276 // ASSIGNMENT OPERATORS
277 // These create a copy of this, then invoke the appropriate
278 // put-here operation on this, passing the copy and x.
279 // Exception: those updated for divideWithRemainder.
280 inline void BigUnsigned::operator +=(const BigUnsigned &x) {
281         BigUnsigned thisCopy(*this);
282         add(thisCopy, x);
283 }
284 inline void BigUnsigned::operator -=(const BigUnsigned &x) {
285         BigUnsigned thisCopy(*this);
286         subtract(thisCopy, x);
287 }
288 inline void BigUnsigned::operator *=(const BigUnsigned &x) {
289         BigUnsigned thisCopy(*this);
290         multiply(thisCopy, x);
291 }
292 inline void BigUnsigned::operator /=(const BigUnsigned &x) {
293         // Updated for divideWithRemainder
294         BigUnsigned thisCopy(*this);
295         thisCopy.divideWithRemainder(x, *this);
296         // quotient left in *this
297         // don't care about remainder left in thisCopy
298 }
299 inline void BigUnsigned::operator %=(const BigUnsigned &x) {
300         // Shortcut (woohoo!)
301         BigUnsigned q;
302         divideWithRemainder(x, q);
303         // remainder left in *this
304         // don't care about quotient left in q
305 }
306 inline void BigUnsigned::operator &=(const BigUnsigned &x) {
307         BigUnsigned thisCopy(*this);
308         bitAnd(thisCopy, x);
309 }
310 inline void BigUnsigned::operator |=(const BigUnsigned &x) {
311         BigUnsigned thisCopy(*this);
312         bitOr(thisCopy, x);
313 }
314 inline void BigUnsigned::operator ^=(const BigUnsigned &x) {
315         BigUnsigned thisCopy(*this);
316         bitXor(thisCopy, x);
317 }
318
319 #endif