xref: /aosp_15_r20/external/pdfium/third_party/bigint/BigInteger.hh (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2014 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker 
5*3ac0a46fSAndroid Build Coastguard Worker // Original code by Matt McCutchen, see the LICENSE file.
6*3ac0a46fSAndroid Build Coastguard Worker 
7*3ac0a46fSAndroid Build Coastguard Worker #ifndef BIGINTEGER_H
8*3ac0a46fSAndroid Build Coastguard Worker #define BIGINTEGER_H
9*3ac0a46fSAndroid Build Coastguard Worker 
10*3ac0a46fSAndroid Build Coastguard Worker #include "BigUnsigned.hh"
11*3ac0a46fSAndroid Build Coastguard Worker 
12*3ac0a46fSAndroid Build Coastguard Worker /* A BigInteger object represents a signed integer of size limited only by
13*3ac0a46fSAndroid Build Coastguard Worker  * available memory.  BigUnsigneds support most mathematical operators and can
14*3ac0a46fSAndroid Build Coastguard Worker  * be converted to and from most primitive integer types.
15*3ac0a46fSAndroid Build Coastguard Worker  *
16*3ac0a46fSAndroid Build Coastguard Worker  * A BigInteger is just an aggregate of a BigUnsigned and a sign.  (It is no
17*3ac0a46fSAndroid Build Coastguard Worker  * longer derived from BigUnsigned because that led to harmful implicit
18*3ac0a46fSAndroid Build Coastguard Worker  * conversions.) */
19*3ac0a46fSAndroid Build Coastguard Worker class BigInteger {
20*3ac0a46fSAndroid Build Coastguard Worker 
21*3ac0a46fSAndroid Build Coastguard Worker public:
22*3ac0a46fSAndroid Build Coastguard Worker 	typedef BigUnsigned::Blk Blk;
23*3ac0a46fSAndroid Build Coastguard Worker 	typedef BigUnsigned::Index Index;
24*3ac0a46fSAndroid Build Coastguard Worker 	typedef BigUnsigned::CmpRes CmpRes;
25*3ac0a46fSAndroid Build Coastguard Worker 	static const CmpRes
26*3ac0a46fSAndroid Build Coastguard Worker 		less    = BigUnsigned::less   ,
27*3ac0a46fSAndroid Build Coastguard Worker 		equal   = BigUnsigned::equal  ,
28*3ac0a46fSAndroid Build Coastguard Worker 		greater = BigUnsigned::greater;
29*3ac0a46fSAndroid Build Coastguard Worker 	// Enumeration for the sign of a BigInteger.
30*3ac0a46fSAndroid Build Coastguard Worker 	enum Sign { negative = -1, zero = 0, positive = 1 };
31*3ac0a46fSAndroid Build Coastguard Worker 
32*3ac0a46fSAndroid Build Coastguard Worker protected:
33*3ac0a46fSAndroid Build Coastguard Worker 	Sign sign;
34*3ac0a46fSAndroid Build Coastguard Worker 	BigUnsigned mag;
35*3ac0a46fSAndroid Build Coastguard Worker 
36*3ac0a46fSAndroid Build Coastguard Worker public:
37*3ac0a46fSAndroid Build Coastguard Worker 	// Constructs zero.
BigInteger()38*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger() : sign(zero), mag() {}
39*3ac0a46fSAndroid Build Coastguard Worker 
40*3ac0a46fSAndroid Build Coastguard Worker 	// Copy constructor
BigInteger(const BigInteger & x)41*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger(const BigInteger &x) : sign(x.sign), mag(x.mag) {}
42*3ac0a46fSAndroid Build Coastguard Worker 
43*3ac0a46fSAndroid Build Coastguard Worker 	// Assignment operator
44*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger& operator=(const BigInteger &x);
45*3ac0a46fSAndroid Build Coastguard Worker 
46*3ac0a46fSAndroid Build Coastguard Worker 	// Constructor that copies from a given array of blocks with a sign.
47*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger(const Blk *b, Index blen, Sign s);
48*3ac0a46fSAndroid Build Coastguard Worker 
49*3ac0a46fSAndroid Build Coastguard Worker 	// Nonnegative constructor that copies from a given array of blocks.
BigInteger(const Blk * b,Index blen)50*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger(const Blk *b, Index blen) : mag(b, blen) {
51*3ac0a46fSAndroid Build Coastguard Worker 		sign = mag.isZero() ? zero : positive;
52*3ac0a46fSAndroid Build Coastguard Worker 	}
53*3ac0a46fSAndroid Build Coastguard Worker 
54*3ac0a46fSAndroid Build Coastguard Worker 	// Constructor from a BigUnsigned and a sign
55*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger(const BigUnsigned &x, Sign s);
56*3ac0a46fSAndroid Build Coastguard Worker 
57*3ac0a46fSAndroid Build Coastguard Worker 	// Nonnegative constructor from a BigUnsigned
BigInteger(const BigUnsigned & x)58*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger(const BigUnsigned &x) : mag(x) {
59*3ac0a46fSAndroid Build Coastguard Worker 		sign = mag.isZero() ? zero : positive;
60*3ac0a46fSAndroid Build Coastguard Worker 	}
61*3ac0a46fSAndroid Build Coastguard Worker 
62*3ac0a46fSAndroid Build Coastguard Worker 	// Constructors from primitive integer types
63*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger(unsigned long  x);
64*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger(         long  x);
65*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger(unsigned int   x);
66*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger(         int   x);
67*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger(unsigned short x);
68*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger(         short x);
69*3ac0a46fSAndroid Build Coastguard Worker 
70*3ac0a46fSAndroid Build Coastguard Worker 	/* Converters to primitive integer types
71*3ac0a46fSAndroid Build Coastguard Worker 	 * The implicit conversion operators caused trouble, so these are now
72*3ac0a46fSAndroid Build Coastguard Worker 	 * named. */
73*3ac0a46fSAndroid Build Coastguard Worker 	unsigned long  toUnsignedLong () const;
74*3ac0a46fSAndroid Build Coastguard Worker 	long           toLong         () const;
75*3ac0a46fSAndroid Build Coastguard Worker 	unsigned int   toUnsignedInt  () const;
76*3ac0a46fSAndroid Build Coastguard Worker 	int            toInt          () const;
77*3ac0a46fSAndroid Build Coastguard Worker 	unsigned short toUnsignedShort() const;
78*3ac0a46fSAndroid Build Coastguard Worker 	short          toShort        () const;
79*3ac0a46fSAndroid Build Coastguard Worker protected:
80*3ac0a46fSAndroid Build Coastguard Worker 	// Helper
81*3ac0a46fSAndroid Build Coastguard Worker 	template <class X> X convertToUnsignedPrimitive() const;
82*3ac0a46fSAndroid Build Coastguard Worker 	template <class X, class UX> X convertToSignedPrimitive() const;
83*3ac0a46fSAndroid Build Coastguard Worker public:
84*3ac0a46fSAndroid Build Coastguard Worker 
85*3ac0a46fSAndroid Build Coastguard Worker 	// ACCESSORS
getSign() const86*3ac0a46fSAndroid Build Coastguard Worker 	Sign getSign() const { return sign; }
87*3ac0a46fSAndroid Build Coastguard Worker 	/* The client can't do any harm by holding a read-only reference to the
88*3ac0a46fSAndroid Build Coastguard Worker 	 * magnitude. */
getMagnitude() const89*3ac0a46fSAndroid Build Coastguard Worker 	const BigUnsigned &getMagnitude() const { return mag; }
90*3ac0a46fSAndroid Build Coastguard Worker 
91*3ac0a46fSAndroid Build Coastguard Worker 	// Some accessors that go through to the magnitude
getLength() const92*3ac0a46fSAndroid Build Coastguard Worker 	Index getLength() const { return mag.getLength(); }
getCapacity() const93*3ac0a46fSAndroid Build Coastguard Worker 	Index getCapacity() const { return mag.getCapacity(); }
getBlock(Index i) const94*3ac0a46fSAndroid Build Coastguard Worker 	Blk getBlock(Index i) const { return mag.getBlock(i); }
isZero() const95*3ac0a46fSAndroid Build Coastguard Worker 	bool isZero() const { return sign == zero; } // A bit special
96*3ac0a46fSAndroid Build Coastguard Worker 
97*3ac0a46fSAndroid Build Coastguard Worker 	// COMPARISONS
98*3ac0a46fSAndroid Build Coastguard Worker 
99*3ac0a46fSAndroid Build Coastguard Worker 	// Compares this to x like Perl's <=>
100*3ac0a46fSAndroid Build Coastguard Worker 	CmpRes compareTo(const BigInteger &x) const;
101*3ac0a46fSAndroid Build Coastguard Worker 
102*3ac0a46fSAndroid Build Coastguard Worker 	// Ordinary comparison operators
operator ==(const BigInteger & x) const103*3ac0a46fSAndroid Build Coastguard Worker 	bool operator ==(const BigInteger &x) const {
104*3ac0a46fSAndroid Build Coastguard Worker 		return sign == x.sign && mag == x.mag;
105*3ac0a46fSAndroid Build Coastguard Worker 	}
operator !=(const BigInteger & x) const106*3ac0a46fSAndroid Build Coastguard Worker 	bool operator !=(const BigInteger &x) const { return !operator ==(x); }
operator <(const BigInteger & x) const107*3ac0a46fSAndroid Build Coastguard Worker 	bool operator < (const BigInteger &x) const { return compareTo(x) == less   ; }
operator <=(const BigInteger & x) const108*3ac0a46fSAndroid Build Coastguard Worker 	bool operator <=(const BigInteger &x) const { return compareTo(x) != greater; }
operator >=(const BigInteger & x) const109*3ac0a46fSAndroid Build Coastguard Worker 	bool operator >=(const BigInteger &x) const { return compareTo(x) != less   ; }
operator >(const BigInteger & x) const110*3ac0a46fSAndroid Build Coastguard Worker 	bool operator > (const BigInteger &x) const { return compareTo(x) == greater; }
111*3ac0a46fSAndroid Build Coastguard Worker 
112*3ac0a46fSAndroid Build Coastguard Worker 	// OPERATORS -- See the discussion in BigUnsigned.hh.
113*3ac0a46fSAndroid Build Coastguard Worker 	void add     (const BigInteger &a, const BigInteger &b);
114*3ac0a46fSAndroid Build Coastguard Worker 	void subtract(const BigInteger &a, const BigInteger &b);
115*3ac0a46fSAndroid Build Coastguard Worker 	void multiply(const BigInteger &a, const BigInteger &b);
116*3ac0a46fSAndroid Build Coastguard Worker 	/* See the comment on BigUnsigned::divideWithRemainder.  Semantics
117*3ac0a46fSAndroid Build Coastguard Worker 	 * differ from those of primitive integers when negatives and/or zeros
118*3ac0a46fSAndroid Build Coastguard Worker 	 * are involved. */
119*3ac0a46fSAndroid Build Coastguard Worker 	void divideWithRemainder(const BigInteger &b, BigInteger &q);
120*3ac0a46fSAndroid Build Coastguard Worker 	void negate(const BigInteger &a);
121*3ac0a46fSAndroid Build Coastguard Worker 
122*3ac0a46fSAndroid Build Coastguard Worker 	/* Bitwise operators are not provided for BigIntegers.  Use
123*3ac0a46fSAndroid Build Coastguard Worker 	 * getMagnitude to get the magnitude and operate on that instead. */
124*3ac0a46fSAndroid Build Coastguard Worker 
125*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger operator +(const BigInteger &x) const;
126*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger operator -(const BigInteger &x) const;
127*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger operator *(const BigInteger &x) const;
128*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger operator /(const BigInteger &x) const;
129*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger operator %(const BigInteger &x) const;
130*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger operator -() const;
131*3ac0a46fSAndroid Build Coastguard Worker 
132*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger& operator +=(const BigInteger &x);
133*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger& operator -=(const BigInteger &x);
134*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger& operator *=(const BigInteger &x);
135*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger& operator /=(const BigInteger &x);
136*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger& operator %=(const BigInteger &x);
137*3ac0a46fSAndroid Build Coastguard Worker 	void flipSign();
138*3ac0a46fSAndroid Build Coastguard Worker 
139*3ac0a46fSAndroid Build Coastguard Worker 	// INCREMENT/DECREMENT OPERATORS
140*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger& operator ++(   );
141*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger operator ++(int);
142*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger& operator --(   );
143*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger operator --(int);
144*3ac0a46fSAndroid Build Coastguard Worker };
145*3ac0a46fSAndroid Build Coastguard Worker 
146*3ac0a46fSAndroid Build Coastguard Worker // NORMAL OPERATORS
147*3ac0a46fSAndroid Build Coastguard Worker /* These create an object to hold the result and invoke
148*3ac0a46fSAndroid Build Coastguard Worker  * the appropriate put-here operation on it, passing
149*3ac0a46fSAndroid Build Coastguard Worker  * this and x.  The new object is then returned. */
operator +(const BigInteger & x) const150*3ac0a46fSAndroid Build Coastguard Worker inline BigInteger BigInteger::operator +(const BigInteger &x) const {
151*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger ans;
152*3ac0a46fSAndroid Build Coastguard Worker 	ans.add(*this, x);
153*3ac0a46fSAndroid Build Coastguard Worker 	return ans;
154*3ac0a46fSAndroid Build Coastguard Worker }
operator -(const BigInteger & x) const155*3ac0a46fSAndroid Build Coastguard Worker inline BigInteger BigInteger::operator -(const BigInteger &x) const {
156*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger ans;
157*3ac0a46fSAndroid Build Coastguard Worker 	ans.subtract(*this, x);
158*3ac0a46fSAndroid Build Coastguard Worker 	return ans;
159*3ac0a46fSAndroid Build Coastguard Worker }
operator *(const BigInteger & x) const160*3ac0a46fSAndroid Build Coastguard Worker inline BigInteger BigInteger::operator *(const BigInteger &x) const {
161*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger ans;
162*3ac0a46fSAndroid Build Coastguard Worker 	ans.multiply(*this, x);
163*3ac0a46fSAndroid Build Coastguard Worker 	return ans;
164*3ac0a46fSAndroid Build Coastguard Worker }
operator /(const BigInteger & x) const165*3ac0a46fSAndroid Build Coastguard Worker inline BigInteger BigInteger::operator /(const BigInteger &x) const {
166*3ac0a46fSAndroid Build Coastguard Worker 	if (x.isZero())
167*3ac0a46fSAndroid Build Coastguard Worker         abort();
168*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger q, r;
169*3ac0a46fSAndroid Build Coastguard Worker 	r = *this;
170*3ac0a46fSAndroid Build Coastguard Worker 	r.divideWithRemainder(x, q);
171*3ac0a46fSAndroid Build Coastguard Worker 	return q;
172*3ac0a46fSAndroid Build Coastguard Worker }
operator %(const BigInteger & x) const173*3ac0a46fSAndroid Build Coastguard Worker inline BigInteger BigInteger::operator %(const BigInteger &x) const {
174*3ac0a46fSAndroid Build Coastguard Worker 	if (x.isZero())
175*3ac0a46fSAndroid Build Coastguard Worker         abort();
176*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger q, r;
177*3ac0a46fSAndroid Build Coastguard Worker 	r = *this;
178*3ac0a46fSAndroid Build Coastguard Worker 	r.divideWithRemainder(x, q);
179*3ac0a46fSAndroid Build Coastguard Worker 	return r;
180*3ac0a46fSAndroid Build Coastguard Worker }
operator -() const181*3ac0a46fSAndroid Build Coastguard Worker inline BigInteger BigInteger::operator -() const {
182*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger ans;
183*3ac0a46fSAndroid Build Coastguard Worker 	ans.negate(*this);
184*3ac0a46fSAndroid Build Coastguard Worker 	return ans;
185*3ac0a46fSAndroid Build Coastguard Worker }
186*3ac0a46fSAndroid Build Coastguard Worker 
187*3ac0a46fSAndroid Build Coastguard Worker /*
188*3ac0a46fSAndroid Build Coastguard Worker  * ASSIGNMENT OPERATORS
189*3ac0a46fSAndroid Build Coastguard Worker  *
190*3ac0a46fSAndroid Build Coastguard Worker  * Now the responsibility for making a temporary copy if necessary
191*3ac0a46fSAndroid Build Coastguard Worker  * belongs to the put-here operations.  See Assignment Operators in
192*3ac0a46fSAndroid Build Coastguard Worker  * BigUnsigned.hh.
193*3ac0a46fSAndroid Build Coastguard Worker  */
operator +=(const BigInteger & x)194*3ac0a46fSAndroid Build Coastguard Worker inline BigInteger& BigInteger::operator +=(const BigInteger &x) {
195*3ac0a46fSAndroid Build Coastguard Worker 	add(*this, x);
196*3ac0a46fSAndroid Build Coastguard Worker 	return *this;
197*3ac0a46fSAndroid Build Coastguard Worker }
operator -=(const BigInteger & x)198*3ac0a46fSAndroid Build Coastguard Worker inline BigInteger& BigInteger::operator -=(const BigInteger &x) {
199*3ac0a46fSAndroid Build Coastguard Worker 	subtract(*this, x);
200*3ac0a46fSAndroid Build Coastguard Worker 	return *this;
201*3ac0a46fSAndroid Build Coastguard Worker }
operator *=(const BigInteger & x)202*3ac0a46fSAndroid Build Coastguard Worker inline BigInteger& BigInteger::operator *=(const BigInteger &x) {
203*3ac0a46fSAndroid Build Coastguard Worker 	multiply(*this, x);
204*3ac0a46fSAndroid Build Coastguard Worker 	return *this;
205*3ac0a46fSAndroid Build Coastguard Worker }
operator /=(const BigInteger & x)206*3ac0a46fSAndroid Build Coastguard Worker inline BigInteger& BigInteger::operator /=(const BigInteger &x) {
207*3ac0a46fSAndroid Build Coastguard Worker 	if (x.isZero())
208*3ac0a46fSAndroid Build Coastguard Worker         abort();
209*3ac0a46fSAndroid Build Coastguard Worker 	/* The following technique is slightly faster than copying *this first
210*3ac0a46fSAndroid Build Coastguard Worker 	 * when x is large. */
211*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger q;
212*3ac0a46fSAndroid Build Coastguard Worker 	divideWithRemainder(x, q);
213*3ac0a46fSAndroid Build Coastguard Worker 	// *this contains the remainder, but we overwrite it with the quotient.
214*3ac0a46fSAndroid Build Coastguard Worker 	*this = q;
215*3ac0a46fSAndroid Build Coastguard Worker 	return *this;
216*3ac0a46fSAndroid Build Coastguard Worker }
operator %=(const BigInteger & x)217*3ac0a46fSAndroid Build Coastguard Worker inline BigInteger& BigInteger::operator %=(const BigInteger &x) {
218*3ac0a46fSAndroid Build Coastguard Worker 	if (x.isZero())
219*3ac0a46fSAndroid Build Coastguard Worker         abort();
220*3ac0a46fSAndroid Build Coastguard Worker 	BigInteger q;
221*3ac0a46fSAndroid Build Coastguard Worker 	// Mods *this by x.  Don't care about quotient left in q.
222*3ac0a46fSAndroid Build Coastguard Worker 	divideWithRemainder(x, q);
223*3ac0a46fSAndroid Build Coastguard Worker 	return *this;
224*3ac0a46fSAndroid Build Coastguard Worker }
225*3ac0a46fSAndroid Build Coastguard Worker // This one is trivial
flipSign()226*3ac0a46fSAndroid Build Coastguard Worker inline void BigInteger::flipSign() {
227*3ac0a46fSAndroid Build Coastguard Worker 	sign = Sign(-sign);
228*3ac0a46fSAndroid Build Coastguard Worker }
229*3ac0a46fSAndroid Build Coastguard Worker 
230*3ac0a46fSAndroid Build Coastguard Worker #endif
231