Old snapshot `bigint-2006.05.01'; see the ChangeLog file.
[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); // Unsafe ``aliased'' call; causes a runtime error.
155         */
156         
157         // PUT-HERE OPERATIONS
158         public:
159         /* These 3: Two read-only operands as arguments.  Result left in *this. */
160         void add(const BigUnsigned &a, const BigUnsigned &b); // Addition
161         void subtract(const BigUnsigned &a, const BigUnsigned &b); // Subtraction
162         void multiply(const BigUnsigned &a, const BigUnsigned &b); // Multiplication
163         /* Divisive stuff
164         * `a.divideWithRemainder(b, q)' is like `q = a / b, a %= b'.
165         * Semantics similar to Donald E. Knuth's are used for / and %,
166         * and these differ from the semantics of primitive-type
167         * / and % under division by zero.
168         * Look in `BigUnsigned.cc' for details.
169         */
170         void divideWithRemainder(const BigUnsigned &b, BigUnsigned &q);
171         void divide(const BigUnsigned &a, const BigUnsigned &b) {
172                 // Division, deprecated and provided for backward compatibility
173                 BigUnsigned a2(a);
174                 a2.divideWithRemainder(b, *this);
175                 // quotient now in *this
176                 // don't care about remainder left in a2
177         }
178         void modulo(const BigUnsigned &a, const BigUnsigned &b) {
179                 // Modular reduction, deprecated and provided for backward compatibility
180                 *this = a;
181                 BigUnsigned q;
182                 divideWithRemainder(b, q);
183                 // remainder now in *this
184                 // don't care about quotient left in q
185         }
186         // Bitwise operations.  Two read-only operands as arguments.  Result left in *this.
187         // These are not provided for BigIntegers; I think that using them on BigIntegers
188         // will discard the sign first.
189         void bitAnd(const BigUnsigned &a, const BigUnsigned &b); // Bitwise AND
190         void bitOr(const BigUnsigned &a, const BigUnsigned &b); // Bitwise OR
191         void bitXor(const BigUnsigned &a, const BigUnsigned &b); // Bitwise XOR
192         
193         // These functions are declared but not defined.  (Sorry.)
194         // Trying to call either will result in a link-time error.
195         void bitShiftLeft(const BigUnsigned &a, unsigned int b); // Bitwise left shift
196         void bitShiftRight(const BigUnsigned &a, unsigned int b); // Bitwise right shift
197         
198         // NORMAL OPERATORS
199         // These perform the operation on this (to the left of the operator)
200         // and x (to the right of the operator) and return a new BigUnsigned with the result.
201         public:
202         BigUnsigned operator +(const BigUnsigned &x) const; // Addition
203         BigUnsigned operator -(const BigUnsigned &x) const; // Subtraction
204         BigUnsigned operator *(const BigUnsigned &x) const; // Multiplication
205         BigUnsigned operator /(const BigUnsigned &x) const; // Division
206         BigUnsigned operator %(const BigUnsigned &x) const; // Modular reduction
207         BigUnsigned operator &(const BigUnsigned &x) const; // Bitwise AND
208         BigUnsigned operator |(const BigUnsigned &x) const; // Bitwise OR
209         BigUnsigned operator ^(const BigUnsigned &x) const; // Bitwise XOR
210         
211         // ASSIGNMENT OPERATORS
212         // These perform the operation on this and x, storing the result into this.
213         public:
214         void operator +=(const BigUnsigned &x); // Addition
215         void operator -=(const BigUnsigned &x); // Subtraction
216         void operator *=(const BigUnsigned &x); // Multiplication
217         void operator /=(const BigUnsigned &x); // Division
218         void operator %=(const BigUnsigned &x); // Modular reduction
219         void operator &=(const BigUnsigned &x); // Bitwise AND
220         void operator |=(const BigUnsigned &x); // Bitwise OR
221         void operator ^=(const BigUnsigned &x); // Bitwise XOR
222         
223         // INCREMENT/DECREMENT OPERATORS
224         // These increase or decrease the number by 1.  To discourage side effects,
225         // these do not return *this, so prefix and postfix behave the same.
226         public:
227         void operator ++(   ); // Prefix  increment
228         void operator ++(int); // Postfix decrement
229         void operator --(   ); // Prefix  increment
230         void operator --(int); // Postfix decrement
231         
232         // Helper function that needs access to BigUnsigned internals
233         friend Blk getShiftedBlock(const BigUnsigned &num, Index x, unsigned int y);
234 };
235
236 // NORMAL OPERATORS
237 /* These create an object to hold the result and invoke
238 * the appropriate put-here operation on it, passing
239 * this and x.  The new object is then returned. */
240 inline BigUnsigned BigUnsigned::operator +(const BigUnsigned &x) const {
241         BigUnsigned ans;
242         ans.add(*this, x);
243         return ans;
244 }
245 inline BigUnsigned BigUnsigned::operator -(const BigUnsigned &x) const {
246         BigUnsigned ans;
247         ans.subtract(*this, x);
248         return ans;
249 }
250 inline BigUnsigned BigUnsigned::operator *(const BigUnsigned &x) const {
251         BigUnsigned ans;
252         ans.multiply(*this, x);
253         return ans;
254 }
255 inline BigUnsigned BigUnsigned::operator /(const BigUnsigned &x) const {
256         BigUnsigned ans;
257         ans.divide(*this, x);
258         return ans;
259 }
260 inline BigUnsigned BigUnsigned::operator %(const BigUnsigned &x) const {
261         BigUnsigned ans;
262         ans.modulo(*this, x);
263         return ans;
264 }
265 inline BigUnsigned BigUnsigned::operator &(const BigUnsigned &x) const {
266         BigUnsigned ans;
267         ans.bitAnd(*this, x);
268         return ans;
269 }
270 inline BigUnsigned BigUnsigned::operator |(const BigUnsigned &x) const {
271         BigUnsigned ans;
272         ans.bitOr(*this, x);
273         return ans;
274 }
275 inline BigUnsigned BigUnsigned::operator ^(const BigUnsigned &x) const {
276         BigUnsigned ans;
277         ans.bitXor(*this, x);
278         return ans;
279 }
280
281 // ASSIGNMENT OPERATORS
282 // These create a copy of this, then invoke the appropriate
283 // put-here operation on this, passing the copy and x.
284 // Exception: those updated for divideWithRemainder.
285 inline void BigUnsigned::operator +=(const BigUnsigned &x) {
286         BigUnsigned thisCopy(*this);
287         add(thisCopy, x);
288 }
289 inline void BigUnsigned::operator -=(const BigUnsigned &x) {
290         BigUnsigned thisCopy(*this);
291         subtract(thisCopy, x);
292 }
293 inline void BigUnsigned::operator *=(const BigUnsigned &x) {
294         BigUnsigned thisCopy(*this);
295         multiply(thisCopy, x);
296 }
297 inline void BigUnsigned::operator /=(const BigUnsigned &x) {
298         // Updated for divideWithRemainder
299         BigUnsigned thisCopy(*this);
300         thisCopy.divideWithRemainder(x, *this);
301         // quotient left in *this
302         // don't care about remainder left in thisCopy
303 }
304 inline void BigUnsigned::operator %=(const BigUnsigned &x) {
305         // Shortcut (woohoo!)
306         BigUnsigned q;
307         divideWithRemainder(x, q);
308         // remainder left in *this
309         // don't care about quotient left in q
310 }
311 inline void BigUnsigned::operator &=(const BigUnsigned &x) {
312         BigUnsigned thisCopy(*this);
313         bitAnd(thisCopy, x);
314 }
315 inline void BigUnsigned::operator |=(const BigUnsigned &x) {
316         BigUnsigned thisCopy(*this);
317         bitOr(thisCopy, x);
318 }
319 inline void BigUnsigned::operator ^=(const BigUnsigned &x) {
320         BigUnsigned thisCopy(*this);
321         bitXor(thisCopy, x);
322 }
323
324 #endif