#include <iostream>
//***OVERVIEW***
//bigint is a method of representing values of any size, up to and including infinity, only limited by the size of availible memory
//each bigint has three parts:
//sign: either negative or positive
//special_value: either none, NaN, or Infinity. special_value overrides value
//value: an endless array representing the magnitude of this bigint
typedef unsigned int size;
namespace CSULLIVAN
{
class bigint
{
public:
//***STATIC CONSTANTS
/*const static bigint one(1);
const static bigint zero(0);
const static bigint negative_one(-1);
const static bigint ten(10);
const static bigint pinfinity("Infinity");
const static bigint ninfinity("-Infinity");
const static bigint nan("NaN");*/
//***CONSTRUCTORS***
bigint();
//PRE: none
//POST: a new bigint with value 0 is created.
bigint(int value);
//PRE: none
//POST: a new bigint with value 'value' is created.
bigint(const char* c);
//PRE: c is a string of only numbers or is 'Infinity', '-Infinity', or 'NaN'
//POST: a new bigint with value equal to the parsed value (base 10) of the string char* c is created
bigint(const bigint& bigint);
//PRE: none
//POST: clones the bigint bigint
//***HELPER FUNCTIONS***
bool is_infinite() const;
//PRE: none
//POST: returns true if the number is infinite. Note that it does not distinguish negative and positive infinity.
bool is_nan() const;
//PRE: none
//POST: returns true if the number is NaN
//***ARITHMETIC OPERATORS***
//***OPERATOR NEGATE***
//PRE: none
//POST: returns a new bigint with a different sign
friend bigint& operator- (const bigint& b1);
//***OPERATOR ASSIGN***
//PRE: none
//POST: sets the value of this bigint to b1
void operator= (const bigint& b1);
void operator= (const int b1);
//***OPERATOR ADD***
//PRE: none
//POST: returns a new bigint with value equal to the sum of b1 and b2
// if b1 and b2 both equal infinity and are of different signs, the result will be 0
// if b1 and b2 both equal infinity and are of the same sign, the result will be infinity of that sign
// if b1 or b2 equal infinity, the result will equal infinity
// if either b1 or b2 equal nan, the result will equal nan
friend bigint& operator+ (const bigint& b1, const bigint& b2);
friend bigint& operator+ (const int b1, const bigint& b2);
friend bigint& operator+ (const bigint& b1, const int b2);
void operator++ ();
void operator+= (const bigint& b2);
void operator+= (const int b2);
//***OPERATOR SUBTRACT***
//PRE: none
//POST: returns a new bigint with value equal to the difference of b1 and b2
// if b1 and b2 both equal infinity and are the same sign, the result will be 0
// if b1 and b2 both equal infinity and are of different signs, the result will be infinity of the sign of b1
// if either b1 or b2 equal infinity, the result will equal infinity
// if either b1 or b2 equal nan, the result will equal nan
friend bigint& operator- (const bigint& b1, const bigint& b2);
friend bigint& operator- (const int b1, const bigint& b2);
friend bigint& operator- (const bigint& b1, const int b2);
void operator-- ();
void operator-= (const bigint& b2);
void operator-= (const int b2);
//***OPERATOR MULTIPLY***
//PRE: none
//POST: returns a new bigint with value equal to the product of b1 and b2
// if b1 or b2 equal infinity, the result will equal infinity, with the signs multiplied
// if either b1 or b2 equal nan, the result will equal nan
friend bigint& operator* (const bigint& b1, const bigint& b2);
friend bigint& operator* (const int b1, const bigint& b2);
friend bigint& operator* (const bigint& b1, const int b2);
void operator*= (const bigint& b2);
void operator*= (const int b2);
//***OPERATOR DIVIDE***
//PRE: none
//POST: returns a new bigint with value equal to the quotient of b1 and b2
// if b1 and b2 both equal infinity, the result will be 1, with the signs multiplied
// if b1 or b2 equal infinity, the result will equal infinity, with the signs multiplied
// if either b1 or b2 equal nan, the result will equal nan
// if b2 equals 0, the result will be nan
friend bigint& operator/ (const bigint& b1, const bigint& b2);
friend bigint& operator/ (const int b1, const bigint& b2);
friend bigint& operator/ (const bigint& b1, const int b2);
void operator/= (const bigint& b2);
void operator/= (const int b2);
//***OPERATOR MODULUS***
//PRE: none
//POST: returns a new bigint with value equal to the remainder of b1 and b2
// if b1 and b2 both equal infinity, the result will be 0, with the signs multiplied
// if b1 or b2 equal infinity, the result will equal infinity, with the signs multiplied
// if either b1 or b2 equal nan, the result will equal nan
// if b2 equals 0, the result will be nan
friend bigint& operator% (const bigint& b1, const bigint& b2);
friend bigint& operator% (const int b1, const bigint& b2);
friend bigint& operator% (const bigint& b1, const int b2);
void operator%= (const bigint& b2);
void operator%= (const int b2);
//***COMPARISON OPERATORS***
//note: for all comparison operators, sign takes precident over special_value and special_value (NaN, Infinity) takes precident over value
//***OPERATOR EQUALS***
//PRE: none
//POST: returns true if the operands are equal
friend bool operator== (const bigint& b1, const bigint& b2);
friend bool operator== (const int b1, const bigint& b2);
friend bool operator== (const bigint& b1, const int b2);
//***OPERATOR NOT EQUALS***
//PRE: none
//POST: returns false if the operands are equal
friend bool operator!= (const bigint& b1, const bigint& b2);
friend bool operator!= (const int b1, const bigint& b2);
friend bool operator!= (const bigint& b1, const int b2);
//***OPERATOR GREATER***
//PRE: none
//POST: returns true if b1 is greater than b2
friend bool operator> (const bigint& b1, const bigint& b2);
friend bool operator> (const int b1, const bigint& b2);
friend bool operator> (const bigint& b1, const int b2);
//***OPERATOR LESSER***
//PRE: none
//POST: returns true if b1 is lesser than b2
friend bool operator< (const bigint& b1, const bigint& b2);
friend bool operator< (const int b1, const bigint& b2);
friend bool operator< (const bigint& b1, const int b2);
//***OPERATOR GREATER OR EQUAL***
//PRE: none
//POST: returns true if b1 is lesser than or equal to b2
friend bool operator>= (const bigint& b1, const bigint& b2);
friend bool operator>= (const int b1, const bigint& b2);
friend bool operator>= (const bigint& b1, const int b2);
//***OPERATOR LESSER***
//PRE: none
//POST: returns true if b1 is lesser than or equal to b2
friend bool operator<= (const bigint& b1, const bigint& b2);
friend bool operator<= (const int b1, const bigint& b2);
friend bool operator<= (const bigint& b1, const int b2);
//IO OPERATORS
//***OPERATOR OUTPUT***
//PRE: none
//POST: prints this bigint to the ostream, returns the ostream
friend std::ostream & operator << (std::ostream & os, const bigint & comp);
//***OPERATOR OUTPUT***
//PRE: none
//POST: reads a bigint from the istream;
friend std::istream & operator >> (std::istream & is, bigint & comp);
private:
typedef unsigned char element;
static const element elemval=10;
element* elem;
size numelem;
bool negative;
int specialValue;
void setEqual(const int i1);
void setEqual(const bigint& b1);
void addbase(const bigint& b1);
void addcore(const element value,const size offset);
void subbase(const int i1);
void subbase(const bigint& b1);
void subcore(const element value,const size offset);
void subcoreinv(const element value,const size offset);
bigint& divisionbase(const bigint& b2);
int comparisonbase(const bigint& b2) const;
int comparisoncore(const bigint& b2) const;
size getLeftmostDigit() const;
size align(const bigint& b2,size,size) const;
void grow(size minsize);
void shrink();
void setSize(size newsize);
};
}