X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Farbint.h;h=468785f315dd81b2311af6bfb77959cd81430672;hp=4b819b9f18ddbc3e0ffe1c74308f3463035dfbe4;hb=dfd021b1505fb3924ae103d8aa27c6200d6ec3fd;hpb=a7da45c62d5a0604785479f5dfeb1c2a65d0f9de diff --git a/src/arbint.h b/src/arbint.h index 4b819b9..468785f 100644 --- a/src/arbint.h +++ b/src/arbint.h @@ -14,18 +14,18 @@ namespace IPDF class Arbint { public: - typedef int64_t digit_t; + typedef uint64_t digit_t; - Arbint(digit_t i); + Arbint(int64_t i); Arbint(const std::vector & digits); Arbint(unsigned n, digit_t d0, ...); Arbint(const std::string & str, const std::string & base="0123456789"); - ~Arbint() {} + virtual ~Arbint() {} Arbint(const Arbint & cpy); - digit_t AsDigit() const + int64_t AsDigit() const { - digit_t digit = (m_digits.size() == 1) ? m_digits[0] : 0xFFFFFFFFFFFFFFFF; + int64_t digit = (m_digits.size() == 1) ? m_digits[0] : 0xBADF00D; return (m_sign) ? -digit : digit; } @@ -45,6 +45,9 @@ namespace IPDF Arbint & operator*=(const Arbint & mul); void Division(const Arbint & div, Arbint & result, Arbint & modulo) const; + Arbint & operator<<=(unsigned amount); + Arbint & operator>>=(unsigned amount); + inline Arbint operator+(const Arbint & add) const { Arbint a(*this); @@ -57,6 +60,20 @@ namespace IPDF a -= add; return a; } + + inline Arbint operator-() + { + Arbint a(*this); + a.m_sign = !a.m_sign; + return a; + } + + inline Arbint operator-() const + { + Arbint a(*this); + a.m_sign = !a.m_sign; + return a; + } inline Arbint operator*(const Arbint & mul) const { @@ -89,6 +106,7 @@ namespace IPDF bool operator==(const Arbint & equ) const; bool operator<(const Arbint & less) const; + inline bool operator!=(const Arbint & equ) const { @@ -107,18 +125,48 @@ namespace IPDF { return !(this->operator<=(grea)); } - + inline Arbint operator>>(unsigned amount) const + { + Arbint result(*this); + result >>= amount; + return result; + } + inline Arbint operator<<(unsigned amount) const + { + Arbint result(*this); + result <<= amount; + return result; + } bool IsZero() const; - - //inline operator double() const {return double(AsDigit());} - inline operator digit_t() const {return AsDigit();} + + inline operator double() const + { + double acc = 0; + for (int i = m_digits.size()-1; i >= 0; --i) + { + acc += (double)m_digits[i]; + acc *= (double)UINT64_MAX + 1.0; + } + if (m_sign) acc *= -1; + return acc; + } + inline operator int64_t() const {return AsDigit();} //inline operator int() const {return int(AsDigit());} unsigned Shrink(); + + inline Arbint Abs() const {Arbint a(*this); a.m_sign = false; return a;} private: Arbint & AddBasic(const Arbint & add); Arbint & SubBasic(const Arbint & sub); + + void GrowDigit(digit_t new_msd); // add a new most significant digit + + bool GetBit(unsigned i) const; + void BitClear(unsigned i); + void BitSet(unsigned i); + std::vector m_digits; bool m_sign; @@ -126,13 +174,18 @@ namespace IPDF }; + + extern "C" { - typedef int64_t digit_t; + typedef uint64_t digit_t; digit_t add_digits(digit_t * dst, digit_t * add, digit_t size); digit_t sub_digits(digit_t * dst, digit_t * add, digit_t size); digit_t mul_digits(digit_t * dst, digit_t mul, digit_t size); + digit_t div_digits(digit_t * dst, digit_t div, digit_t size, digit_t * rem); } + + } #endif //_ARBINT_H