mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			215 lines
		
	
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			215 lines
		
	
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#ifndef BIGINTEGER_H
 | 
						|
#define BIGINTEGER_H
 | 
						|
 | 
						|
#include "BigUnsigned.hh"
 | 
						|
 | 
						|
/* A BigInteger object represents a signed integer of size limited only by
 | 
						|
 * available memory.  BigUnsigneds support most mathematical operators and can
 | 
						|
 * be converted to and from most primitive integer types.
 | 
						|
 *
 | 
						|
 * A BigInteger is just an aggregate of a BigUnsigned and a sign.  (It is no
 | 
						|
 * longer derived from BigUnsigned because that led to harmful implicit
 | 
						|
 * conversions.) */
 | 
						|
class BigInteger {
 | 
						|
 | 
						|
public:
 | 
						|
	typedef BigUnsigned::Blk Blk;
 | 
						|
	typedef BigUnsigned::Index Index;
 | 
						|
	typedef BigUnsigned::CmpRes CmpRes;
 | 
						|
	static const CmpRes
 | 
						|
		less    = BigUnsigned::less   ,
 | 
						|
		equal   = BigUnsigned::equal  ,
 | 
						|
		greater = BigUnsigned::greater;
 | 
						|
	// Enumeration for the sign of a BigInteger.
 | 
						|
	enum Sign { negative = -1, zero = 0, positive = 1 };
 | 
						|
 | 
						|
protected:
 | 
						|
	Sign sign;
 | 
						|
	BigUnsigned mag;
 | 
						|
 | 
						|
public:
 | 
						|
	// Constructs zero.
 | 
						|
	BigInteger() : sign(zero), mag() {}
 | 
						|
 | 
						|
	// Copy constructor
 | 
						|
	BigInteger(const BigInteger &x) : sign(x.sign), mag(x.mag) {};
 | 
						|
 | 
						|
	// Assignment operator
 | 
						|
	void operator=(const BigInteger &x);
 | 
						|
 | 
						|
	// Constructor that copies from a given array of blocks with a sign.
 | 
						|
	BigInteger(const Blk *b, Index blen, Sign s);
 | 
						|
 | 
						|
	// Nonnegative constructor that copies from a given array of blocks.
 | 
						|
	BigInteger(const Blk *b, Index blen) : mag(b, blen) {
 | 
						|
		sign = mag.isZero() ? zero : positive;
 | 
						|
	}
 | 
						|
 | 
						|
	// Constructor from a BigUnsigned and a sign
 | 
						|
	BigInteger(const BigUnsigned &x, Sign s);
 | 
						|
 | 
						|
	// Nonnegative constructor from a BigUnsigned
 | 
						|
	BigInteger(const BigUnsigned &x) : mag(x) {
 | 
						|
		sign = mag.isZero() ? zero : positive;
 | 
						|
	}
 | 
						|
 | 
						|
	// Constructors from primitive integer types
 | 
						|
	BigInteger(unsigned long  x);
 | 
						|
	BigInteger(         long  x);
 | 
						|
	BigInteger(unsigned int   x);
 | 
						|
	BigInteger(         int   x);
 | 
						|
	BigInteger(unsigned short x);
 | 
						|
	BigInteger(         short x);
 | 
						|
 | 
						|
	/* Converters to primitive integer types
 | 
						|
	 * The implicit conversion operators caused trouble, so these are now
 | 
						|
	 * named. */
 | 
						|
	unsigned long  toUnsignedLong () const;
 | 
						|
	long           toLong         () const;
 | 
						|
	unsigned int   toUnsignedInt  () const;
 | 
						|
	int            toInt          () const;
 | 
						|
	unsigned short toUnsignedShort() const;
 | 
						|
	short          toShort        () const;
 | 
						|
protected:
 | 
						|
	// Helper
 | 
						|
	template <class X> X convertToUnsignedPrimitive() const;
 | 
						|
	template <class X, class UX> X convertToSignedPrimitive() const;
 | 
						|
public:
 | 
						|
 | 
						|
	// ACCESSORS
 | 
						|
	Sign getSign() const { return sign; }
 | 
						|
	/* The client can't do any harm by holding a read-only reference to the
 | 
						|
	 * magnitude. */
 | 
						|
	const BigUnsigned &getMagnitude() const { return mag; }
 | 
						|
 | 
						|
	// Some accessors that go through to the magnitude
 | 
						|
	Index getLength() const { return mag.getLength(); }
 | 
						|
	Index getCapacity() const { return mag.getCapacity(); }
 | 
						|
	Blk getBlock(Index i) const { return mag.getBlock(i); }
 | 
						|
	bool isZero() const { return sign == zero; } // A bit special
 | 
						|
 | 
						|
	// COMPARISONS
 | 
						|
 | 
						|
	// Compares this to x like Perl's <=>
 | 
						|
	CmpRes compareTo(const BigInteger &x) const;
 | 
						|
 | 
						|
	// Ordinary comparison operators
 | 
						|
	bool operator ==(const BigInteger &x) const {
 | 
						|
		return sign == x.sign && mag == x.mag;
 | 
						|
	}
 | 
						|
	bool operator !=(const BigInteger &x) const { return !operator ==(x); };
 | 
						|
	bool operator < (const BigInteger &x) const { return compareTo(x) == less   ; }
 | 
						|
	bool operator <=(const BigInteger &x) const { return compareTo(x) != greater; }
 | 
						|
	bool operator >=(const BigInteger &x) const { return compareTo(x) != less   ; }
 | 
						|
	bool operator > (const BigInteger &x) const { return compareTo(x) == greater; }
 | 
						|
 | 
						|
	// OPERATORS -- See the discussion in BigUnsigned.hh.
 | 
						|
	void add     (const BigInteger &a, const BigInteger &b);
 | 
						|
	void subtract(const BigInteger &a, const BigInteger &b);
 | 
						|
	void multiply(const BigInteger &a, const BigInteger &b);
 | 
						|
	/* See the comment on BigUnsigned::divideWithRemainder.  Semantics
 | 
						|
	 * differ from those of primitive integers when negatives and/or zeros
 | 
						|
	 * are involved. */
 | 
						|
	void divideWithRemainder(const BigInteger &b, BigInteger &q);
 | 
						|
	void negate(const BigInteger &a);
 | 
						|
	
 | 
						|
	/* Bitwise operators are not provided for BigIntegers.  Use
 | 
						|
	 * getMagnitude to get the magnitude and operate on that instead. */
 | 
						|
 | 
						|
	BigInteger operator +(const BigInteger &x) const;
 | 
						|
	BigInteger operator -(const BigInteger &x) const;
 | 
						|
	BigInteger operator *(const BigInteger &x) const;
 | 
						|
	BigInteger operator /(const BigInteger &x) const;
 | 
						|
	BigInteger operator %(const BigInteger &x) const;
 | 
						|
	BigInteger operator -() const;
 | 
						|
 | 
						|
	void operator +=(const BigInteger &x);
 | 
						|
	void operator -=(const BigInteger &x);
 | 
						|
	void operator *=(const BigInteger &x);
 | 
						|
	void operator /=(const BigInteger &x);
 | 
						|
	void operator %=(const BigInteger &x);
 | 
						|
	void flipSign();
 | 
						|
 | 
						|
	// INCREMENT/DECREMENT OPERATORS
 | 
						|
	void operator ++(   );
 | 
						|
	void operator ++(int);
 | 
						|
	void operator --(   );
 | 
						|
	void operator --(int);
 | 
						|
};
 | 
						|
 | 
						|
// NORMAL OPERATORS
 | 
						|
/* These create an object to hold the result and invoke
 | 
						|
 * the appropriate put-here operation on it, passing
 | 
						|
 * this and x.  The new object is then returned. */
 | 
						|
inline BigInteger BigInteger::operator +(const BigInteger &x) const {
 | 
						|
	BigInteger ans;
 | 
						|
	ans.add(*this, x);
 | 
						|
	return ans;
 | 
						|
}
 | 
						|
inline BigInteger BigInteger::operator -(const BigInteger &x) const {
 | 
						|
	BigInteger ans;
 | 
						|
	ans.subtract(*this, x);
 | 
						|
	return ans;
 | 
						|
}
 | 
						|
inline BigInteger BigInteger::operator *(const BigInteger &x) const {
 | 
						|
	BigInteger ans;
 | 
						|
	ans.multiply(*this, x);
 | 
						|
	return ans;
 | 
						|
}
 | 
						|
inline BigInteger BigInteger::operator /(const BigInteger &x) const {
 | 
						|
	if (x.isZero()) throw "BigInteger::operator /: division by zero";
 | 
						|
	BigInteger q, r;
 | 
						|
	r = *this;
 | 
						|
	r.divideWithRemainder(x, q);
 | 
						|
	return q;
 | 
						|
}
 | 
						|
inline BigInteger BigInteger::operator %(const BigInteger &x) const {
 | 
						|
	if (x.isZero()) throw "BigInteger::operator %: division by zero";
 | 
						|
	BigInteger q, r;
 | 
						|
	r = *this;
 | 
						|
	r.divideWithRemainder(x, q);
 | 
						|
	return r;
 | 
						|
}
 | 
						|
inline BigInteger BigInteger::operator -() const {
 | 
						|
	BigInteger ans;
 | 
						|
	ans.negate(*this);
 | 
						|
	return ans;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * ASSIGNMENT OPERATORS
 | 
						|
 * 
 | 
						|
 * Now the responsibility for making a temporary copy if necessary
 | 
						|
 * belongs to the put-here operations.  See Assignment Operators in
 | 
						|
 * BigUnsigned.hh.
 | 
						|
 */
 | 
						|
inline void BigInteger::operator +=(const BigInteger &x) {
 | 
						|
	add(*this, x);
 | 
						|
}
 | 
						|
inline void BigInteger::operator -=(const BigInteger &x) {
 | 
						|
	subtract(*this, x);
 | 
						|
}
 | 
						|
inline void BigInteger::operator *=(const BigInteger &x) {
 | 
						|
	multiply(*this, x);
 | 
						|
}
 | 
						|
inline void BigInteger::operator /=(const BigInteger &x) {
 | 
						|
	if (x.isZero()) throw "BigInteger::operator /=: division by zero";
 | 
						|
	/* The following technique is slightly faster than copying *this first
 | 
						|
	 * when x is large. */
 | 
						|
	BigInteger q;
 | 
						|
	divideWithRemainder(x, q);
 | 
						|
	// *this contains the remainder, but we overwrite it with the quotient.
 | 
						|
	*this = q;
 | 
						|
}
 | 
						|
inline void BigInteger::operator %=(const BigInteger &x) {
 | 
						|
	if (x.isZero()) throw "BigInteger::operator %=: division by zero";
 | 
						|
	BigInteger q;
 | 
						|
	// Mods *this by x.  Don't care about quotient left in q.
 | 
						|
	divideWithRemainder(x, q);
 | 
						|
}
 | 
						|
// This one is trivial
 | 
						|
inline void BigInteger::flipSign() {
 | 
						|
	sign = Sign(-sign);
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |