1e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved.
2e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// found in the LICENSE file.
4e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
5e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Original code by Matt McCutchen, see the LICENSE file.
6e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
7e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include "BigInteger.hh"
8e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
9e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigInteger::operator =(const BigInteger &x) {
10e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// Calls like a = a have no effect
11e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (this == &x)
12e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return;
13e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// Copy sign
14e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	sign = x.sign;
15e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// Copy the rest
16e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	mag = x.mag;
17e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
18e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigInteger::BigInteger(const Blk *b, Index blen, Sign s) : mag(b, blen) {
20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	switch (s) {
21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	case zero:
22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		if (!mag.isZero())
23e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            abort();
24e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		sign = zero;
25e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		break;
26e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	case positive:
27e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	case negative:
28e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// If the magnitude is zero, force the sign to zero.
29e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		sign = mag.isZero() ? zero : s;
30e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		break;
31e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	default:
32e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		/* g++ seems to be optimizing out this case on the assumption
33e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 * that the sign is a valid member of the enumeration.  Oh well. */
34e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        abort();
35e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
36e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
37e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
38e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigInteger::BigInteger(const BigUnsigned &x, Sign s) : mag(x) {
39e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	switch (s) {
40e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	case zero:
41e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		if (!mag.isZero())
42e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov            abort();
43e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		sign = zero;
44e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		break;
45e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	case positive:
46e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	case negative:
47e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// If the magnitude is zero, force the sign to zero.
48e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		sign = mag.isZero() ? zero : s;
49e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		break;
50e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	default:
51e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		/* g++ seems to be optimizing out this case on the assumption
52e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 * that the sign is a valid member of the enumeration.  Oh well. */
53e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        abort();
54e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
55e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
56e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
57e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* CONSTRUCTION FROM PRIMITIVE INTEGERS
58e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Same idea as in BigUnsigned.cc, except that negative input results in a
59e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * negative BigInteger instead of an exception. */
60e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
61e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Done longhand to let us use initialization.
62e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigInteger::BigInteger(unsigned long  x) : mag(x) { sign = mag.isZero() ? zero : positive; }
63e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigInteger::BigInteger(unsigned int   x) : mag(x) { sign = mag.isZero() ? zero : positive; }
64e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigInteger::BigInteger(unsigned short x) : mag(x) { sign = mag.isZero() ? zero : positive; }
65e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
66e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// For signed input, determine the desired magnitude and sign separately.
67e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
68e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovnamespace {
69e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	template <class X, class UX>
70e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	BigInteger::Blk magOf(X x) {
71e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		/* UX(...) cast needed to stop short(-2^15), which negates to
72e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 * itself, from sign-extending in the conversion to Blk. */
73e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return BigInteger::Blk(x < 0 ? UX(-x) : x);
74e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
75e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	template <class X>
76e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	BigInteger::Sign signOf(X x) {
77e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return (x == 0) ? BigInteger::zero
78e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			: (x > 0) ? BigInteger::positive
79e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			: BigInteger::negative;
80e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
81e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
82e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
83e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigInteger::BigInteger(long  x) : sign(signOf(x)), mag(magOf<long , unsigned long >(x)) {}
84e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigInteger::BigInteger(int   x) : sign(signOf(x)), mag(magOf<int  , unsigned int  >(x)) {}
85e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigInteger::BigInteger(short x) : sign(signOf(x)), mag(magOf<short, unsigned short>(x)) {}
86e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
87e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// CONVERSION TO PRIMITIVE INTEGERS
88e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
89e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Reuse BigUnsigned's conversion to an unsigned primitive integer.
90e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * The friend is a separate function rather than
91e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * BigInteger::convertToUnsignedPrimitive to avoid requiring BigUnsigned to
92e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * declare BigInteger. */
93e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovtemplate <class X>
94e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovinline X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a) {
95e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	return a.convertToPrimitive<X>();
96e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
97e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
98e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovtemplate <class X>
99e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovX BigInteger::convertToUnsignedPrimitive() const {
100e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (sign == negative)
101e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        abort();
102e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	else
103e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return convertBigUnsignedToPrimitiveAccess<X>(mag);
104e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
105e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
106e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* Similar to BigUnsigned::convertToPrimitive, but split into two cases for
107e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * nonnegative and negative numbers. */
108e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovtemplate <class X, class UX>
109e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovX BigInteger::convertToSignedPrimitive() const {
110e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (sign == zero)
111e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return 0;
112e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	else if (mag.getLength() == 1) {
113e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// The single block might fit in an X.  Try the conversion.
114e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		Blk b = mag.getBlock(0);
115e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		if (sign == positive) {
116e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			X x = X(b);
117e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			if (x >= 0 && Blk(x) == b)
118e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				return x;
119e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		} else {
120e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			X x = -X(b);
121e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			/* UX(...) needed to avoid rejecting conversion of
122e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			 * -2^15 to a short. */
123e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			if (x < 0 && Blk(UX(-x)) == b)
124e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov				return x;
125e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		}
126e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// Otherwise fall through.
127e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
128e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    abort();
129e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
130e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
131e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovunsigned long  BigInteger::toUnsignedLong () const { return convertToUnsignedPrimitive<unsigned long >       (); }
132e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovunsigned int   BigInteger::toUnsignedInt  () const { return convertToUnsignedPrimitive<unsigned int  >       (); }
133e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovunsigned short BigInteger::toUnsignedShort() const { return convertToUnsignedPrimitive<unsigned short>       (); }
134e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovlong           BigInteger::toLong         () const { return convertToSignedPrimitive  <long , unsigned long> (); }
135e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovint            BigInteger::toInt          () const { return convertToSignedPrimitive  <int  , unsigned int>  (); }
136e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovshort          BigInteger::toShort        () const { return convertToSignedPrimitive  <short, unsigned short>(); }
137e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
138e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// COMPARISON
139e6986e1e8d4a57987f47c215490cb080a65ee29aSvet GanovBigInteger::CmpRes BigInteger::compareTo(const BigInteger &x) const {
140e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// A greater sign implies a greater number
141e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (sign < x.sign)
142e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return less;
143e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	else if (sign > x.sign)
144e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return greater;
145e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	else switch (sign) {
146e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// If the signs are the same...
147e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	case zero:
148e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return equal; // Two zeros are equal
149e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	case positive:
150e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// Compare the magnitudes
151e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return mag.compareTo(x.mag);
152e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	case negative:
153e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// Compare the magnitudes, but return the opposite result
154e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return CmpRes(-mag.compareTo(x.mag));
155e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	default:
156e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        abort();
157e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
158e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
159e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
160e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/* COPY-LESS OPERATIONS
161e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * These do some messing around to determine the sign of the result,
162e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * then call one of BigUnsigned's copy-less operations. */
163e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
164e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// See remarks about aliased calls in BigUnsigned.cc .
165e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define DTRT_ALIASED(cond, op) \
166e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (cond) { \
167e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		BigInteger tmpThis; \
168e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		tmpThis.op; \
169e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		*this = tmpThis; \
170e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return; \
171e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
172e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
173e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigInteger::add(const BigInteger &a, const BigInteger &b) {
174e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	DTRT_ALIASED(this == &a || this == &b, add(a, b));
175e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// If one argument is zero, copy the other.
176e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (a.sign == zero)
177e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		operator =(b);
178e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	else if (b.sign == zero)
179e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		operator =(a);
180e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// If the arguments have the same sign, take the
181e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// common sign and add their magnitudes.
182e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	else if (a.sign == b.sign) {
183e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		sign = a.sign;
184e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		mag.add(a.mag, b.mag);
185e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	} else {
186e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// Otherwise, their magnitudes must be compared.
187e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		switch (a.mag.compareTo(b.mag)) {
188e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		case equal:
189e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			// If their magnitudes are the same, copy zero.
190e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			mag = 0;
191e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			sign = zero;
192e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			break;
193e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			// Otherwise, take the sign of the greater, and subtract
194e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			// the lesser magnitude from the greater magnitude.
195e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		case greater:
196e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			sign = a.sign;
197e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			mag.subtract(a.mag, b.mag);
198e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			break;
199e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		case less:
200e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			sign = b.sign;
201e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			mag.subtract(b.mag, a.mag);
202e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			break;
203e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		}
204e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
205e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
206e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
207e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigInteger::subtract(const BigInteger &a, const BigInteger &b) {
208e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// Notice that this routine is identical to BigInteger::add,
209e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// if one replaces b.sign by its opposite.
210e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	DTRT_ALIASED(this == &a || this == &b, subtract(a, b));
211e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// If a is zero, copy b and flip its sign.  If b is zero, copy a.
212e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (a.sign == zero) {
213e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		mag = b.mag;
214e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// Take the negative of _b_'s, sign, not ours.
215e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// Bug pointed out by Sam Larkin on 2005.03.30.
216e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		sign = Sign(-b.sign);
217e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	} else if (b.sign == zero)
218e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		operator =(a);
219e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// If their signs differ, take a.sign and add the magnitudes.
220e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	else if (a.sign != b.sign) {
221e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		sign = a.sign;
222e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		mag.add(a.mag, b.mag);
223e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	} else {
224e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// Otherwise, their magnitudes must be compared.
225e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		switch (a.mag.compareTo(b.mag)) {
226e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			// If their magnitudes are the same, copy zero.
227e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		case equal:
228e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			mag = 0;
229e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			sign = zero;
230e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			break;
231e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			// If a's magnitude is greater, take a.sign and
232e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			// subtract a from b.
233e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		case greater:
234e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			sign = a.sign;
235e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			mag.subtract(a.mag, b.mag);
236e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			break;
237e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			// If b's magnitude is greater, take the opposite
238e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			// of b.sign and subtract b from a.
239e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		case less:
240e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			sign = Sign(-b.sign);
241e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			mag.subtract(b.mag, a.mag);
242e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			break;
243e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		}
244e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
245e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
246e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
247e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigInteger::multiply(const BigInteger &a, const BigInteger &b) {
248e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	DTRT_ALIASED(this == &a || this == &b, multiply(a, b));
249e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// If one object is zero, copy zero and return.
250e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (a.sign == zero || b.sign == zero) {
251e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		sign = zero;
252e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		mag = 0;
253e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return;
254e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
255e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// If the signs of the arguments are the same, the result
256e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// is positive, otherwise it is negative.
257e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	sign = (a.sign == b.sign) ? positive : negative;
258e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// Multiply the magnitudes.
259e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	mag.multiply(a.mag, b.mag);
260e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
261e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
262e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov/*
263e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * DIVISION WITH REMAINDER
264e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Please read the comments before the definition of
265e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * `BigUnsigned::divideWithRemainder' in `BigUnsigned.cc' for lots of
266e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * information you should know before reading this function.
267e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *
268e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Following Knuth, I decree that x / y is to be
269e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * 0 if y==0 and floor(real-number x / y) if y!=0.
270e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Then x % y shall be x - y*(integer x / y).
271e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *
272e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Note that x = y * (x / y) + (x % y) always holds.
273e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * In addition, (x % y) is from 0 to y - 1 if y > 0,
274e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * and from -(|y| - 1) to 0 if y < 0.  (x % y) = x if y = 0.
275e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *
276e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov * Examples: (q = a / b, r = a % b)
277e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *	a	b	q	r
278e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *	===	===	===	===
279e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *	4	3	1	1
280e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *	-4	3	-2	2
281e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *	4	-3	-2	-2
282e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov *	-4	-3	1	-1
283e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov */
284e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigInteger::divideWithRemainder(const BigInteger &b, BigInteger &q) {
285e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// Defend against aliased calls;
286e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// same idea as in BigUnsigned::divideWithRemainder .
287e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (this == &q)
288e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        abort();
289e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (this == &b || &q == &b) {
290e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		BigInteger tmpB(b);
291e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		divideWithRemainder(tmpB, q);
292e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return;
293e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
294e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
295e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// Division by zero gives quotient 0 and remainder *this
296e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (b.sign == zero) {
297e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		q.mag = 0;
298e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		q.sign = zero;
299e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return;
300e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
301e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// 0 / b gives quotient 0 and remainder 0
302e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (sign == zero) {
303e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		q.mag = 0;
304e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		q.sign = zero;
305e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		return;
306e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
307e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
308e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// Here *this != 0, b != 0.
309e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
310e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// Do the operands have the same sign?
311e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (sign == b.sign) {
312e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// Yes: easy case.  Quotient is zero or positive.
313e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		q.sign = positive;
314e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	} else {
315e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// No: harder case.  Quotient is negative.
316e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		q.sign = negative;
317e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// Decrease the magnitude of the dividend by one.
318e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		mag--;
319e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		/*
320e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 * We tinker with the dividend before and with the
321e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 * quotient and remainder after so that the result
322e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 * comes out right.  To see why it works, consider the following
323e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 * list of examples, where A is the magnitude-decreased
324e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 * a, Q and R are the results of BigUnsigned division
325e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 * with remainder on A and |b|, and q and r are the
326e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 * final results we want:
327e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 *
328e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 *	a	A	b	Q	R	q	r
329e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 *	-3	-2	3	0	2	-1	0
330e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 *	-4	-3	3	1	0	-2	2
331e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 *	-5	-4	3	1	1	-2	1
332e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 *	-6	-5	3	1	2	-2	0
333e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 *
334e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 * It appears that we need a total of 3 corrections:
335e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 * Decrease the magnitude of a to get A.  Increase the
336e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 * magnitude of Q to get q (and make it negative).
337e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 * Find r = (b - 1) - R and give it the desired sign.
338e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		 */
339e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
340e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
341e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// Divide the magnitudes.
342e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	mag.divideWithRemainder(b.mag, q.mag);
343e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
344e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (sign != b.sign) {
345e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// More for the harder case (as described):
346e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// Increase the magnitude of the quotient by one.
347e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		q.mag++;
348e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		// Modify the remainder.
349e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		mag.subtract(b.mag, mag);
350e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		mag--;
351e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
352e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
353e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// Sign of the remainder is always the sign of the divisor b.
354e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	sign = b.sign;
355e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
356e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// Set signs to zero as necessary.  (Thanks David Allen!)
357e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (mag.isZero())
358e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		sign = zero;
359e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (q.mag.isZero())
360e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		q.sign = zero;
361e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
362e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// WHEW!!!
363e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
364e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
365e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Negation
366e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigInteger::negate(const BigInteger &a) {
367e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	DTRT_ALIASED(this == &a, negate(a));
368e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// Copy a's magnitude
369e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	mag = a.mag;
370e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	// Copy the opposite of a.sign
371e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	sign = Sign(-a.sign);
372e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
373e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
374e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// INCREMENT/DECREMENT OPERATORS
375e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
376e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Prefix increment
377e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigInteger::operator ++() {
378e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (sign == negative) {
379e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		mag--;
380e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		if (mag == 0)
381e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			sign = zero;
382e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	} else {
383e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		mag++;
384e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		sign = positive; // if not already
385e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
386e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
387e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
388e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Postfix increment: same as prefix
389e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigInteger::operator ++(int) {
390e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	operator ++();
391e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
392e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
393e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Prefix decrement
394e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigInteger::operator --() {
395e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	if (sign == positive) {
396e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		mag--;
397e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		if (mag == 0)
398e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov			sign = zero;
399e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	} else {
400e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		mag++;
401e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov		sign = negative;
402e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	}
403e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
404e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
405e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov// Postfix decrement: same as prefix
406e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovvoid BigInteger::operator --(int) {
407e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov	operator --();
408e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov}
409e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
410