#pragma once #include #include #include #include #include class Bigint{ public: typedef uint32_t digit_t; typedef int32_t sdigit_t; typedef uint64_t longdigit_t; typedef int64_t slongdigit_t; static const int digit_bits=8*sizeof(digit_t); private: std::vector digits; int sign; static void add(Bigint&,const Bigint&); //ignores sign of arguments static void subtract(Bigint&,const Bigint&); //ignores sign of arguments; assumes a>=b static Bigint product(const Bigint&,const Bigint&); void shrink(); void normalise(); void checkconsistent(); std::pair divmod(const Bigint&,int depth,int maxdepth) const; //ignores all signs public: Bigint(); Bigint(const Bigint&)=default; Bigint(Bigint&&); explicit Bigint(const std::string&); explicit Bigint(sdigit_t); explicit Bigint(digit_t); explicit Bigint(slongdigit_t); explicit Bigint(longdigit_t); Bigint& operator=(const Bigint&)=default; Bigint& operator=(Bigint&&); Bigint& operator=(slongdigit_t); Bigint& operator=(longdigit_t); Bigint& operator=(sdigit_t); Bigint& operator=(digit_t); Bigint& operator+=(const Bigint&); Bigint& operator-=(const Bigint&); Bigint& operator*=(const Bigint&); Bigint& operator+=(slongdigit_t); Bigint& operator-=(slongdigit_t); Bigint& operator*=(slongdigit_t); Bigint& operator<<=(int); Bigint& operator>>=(int); Bigint& negate(); Bigint operator+(const Bigint&) const; Bigint operator-(const Bigint&) const; Bigint operator*(const Bigint&) const; Bigint operator+(slongdigit_t) const; Bigint operator-(slongdigit_t) const; Bigint operator*(slongdigit_t) const; Bigint operator<<(int) const; Bigint operator>>(int) const; //Uses *mathematical* division-with-remainder. //If we look at {q,r} = x.divmod(y), then x = q*y + r, and 0<=r<|q|. This is *not* compatible with many other //programming languages (and, for that matter, the C++ built-in behaviour). std::pair divmod(const Bigint&) const; bool operator==(const Bigint&) const; bool operator!=(const Bigint&) const; bool operator<(const Bigint&) const; bool operator>(const Bigint&) const; bool operator<=(const Bigint&) const; bool operator>=(const Bigint&) const; bool operator==(slongdigit_t) const; bool operator!=(slongdigit_t) const; bool operator<(slongdigit_t) const; bool operator>(slongdigit_t) const; bool operator<=(slongdigit_t) const; bool operator>=(slongdigit_t) const; int compare(const Bigint&) const; //-1: <; 0: ==; 1: > int compare(slongdigit_t) const; int compareAbs(const Bigint&) const; //-1: <; 0: ==; 1: >; disregards sign int compareAbs(slongdigit_t) const; int bitcount() const; slongdigit_t lowdigits() const; bool even() const; bool odd() const; std::string serialiseMantissa() const; //stores everything but the sign //restores non-negative number; can throw invalid_argument void deserialiseMantissa(const std::string&); std::vector bits() const; friend std::istream& operator>>(std::istream&,Bigint&); friend std::ostream& operator<<(std::ostream&,Bigint); digit_t _digit(int idx) const; static Bigint mone; static Bigint zero; static Bigint one; static Bigint two; }; std::istream& operator>>(std::istream&,Bigint&); std::ostream& operator<<(std::ostream&,Bigint);