digit_t is now unsigned, asm division for 1 digit
[ipdf/code.git] / src / arbint.h
1 /**
2  * @file arbint.h
3  * @brief Arbitrary sized integer declarations
4  * @see arbint.cpp
5  */
6  
7 #ifndef _ARBINT_H
8 #define _ARBINT_H
9
10 #include "common.h"
11
12 namespace IPDF
13 {
14         class Arbint
15         {
16                 public:
17                         typedef uint64_t digit_t;
18                 
19                         Arbint(int64_t i);
20                         Arbint(const std::vector<digit_t> & digits);
21                         Arbint(unsigned n, digit_t d0, ...);
22                         Arbint(const std::string & str, const std::string & base="0123456789");
23                         virtual ~Arbint() {}
24                         Arbint(const Arbint & cpy);
25                         
26                         int64_t AsDigit() const
27                         {
28                                 int64_t digit = (m_digits.size() == 1) ? m_digits[0] : 0x7FFFFFFFFFFFFFFF;
29                                 return (m_sign) ? -digit : digit;
30                         }
31                         
32                         inline bool Sign() const {return m_sign;}
33                         inline char SignChar() const {return (m_sign) ? '-' : '+';}
34                         std::string DigitStr() const;
35
36                         std::string Str(const std::string & base="0123456789") const;
37                         inline std::string Str(const char * base) const
38                         {
39                                 return Str(std::string(base));
40                         }
41                         
42                         Arbint & operator=(const Arbint & equ);
43                         Arbint & operator+=(const Arbint & add);
44                         Arbint & operator-=(const Arbint & sub);
45                         Arbint & operator*=(const Arbint & mul);
46                         void Division(const Arbint & div, Arbint & result, Arbint & modulo) const;
47                         
48                         Arbint & operator<<=(unsigned amount);
49                         Arbint & operator>>=(unsigned amount);
50                         
51                         inline Arbint operator+(const Arbint & add) const 
52                         {
53                                 Arbint a(*this);
54                                 a += add;
55                                 return a;
56                         }
57                         inline Arbint operator-(const Arbint & add) const 
58                         {
59                                 Arbint a(*this);
60                                 a -= add;
61                                 return a;
62                         }
63
64                         inline Arbint operator-()
65                         {
66                                 Arbint a(*this);
67                                 a.m_sign = !a.m_sign;
68                                 return a;
69                         }
70                         
71                         inline Arbint operator*(const Arbint & mul) const
72                         {
73                                 Arbint a(*this);
74                                 a *= mul;
75                                 return a;
76                         }
77                         
78                         inline Arbint & operator/=(const Arbint & div)
79                         {
80                                 Arbint result(0L);
81                                 Arbint remainder(0L);
82                                 this->Division(div, result, remainder);
83                                 this->operator=(result);
84                                 return *this;
85                         }
86                         inline Arbint operator/(const Arbint & div)
87                         {
88                                 Arbint cpy(*this);
89                                 cpy /= div;
90                                 return cpy;
91                         }
92                         inline Arbint operator%(const Arbint & div)
93                         {
94                                 Arbint result(0L);
95                                 Arbint remainder(0L);
96                                 this->Division(div, result, remainder);
97                                 return remainder;
98                         }
99                         
100                         bool operator==(const Arbint & equ) const;
101                         bool operator<(const Arbint & less) const;
102
103                         inline bool operator!=(const Arbint & equ) const 
104                         {
105                                 return !(this->operator==(equ));
106                         }
107                         inline bool operator<=(const Arbint & leq) const 
108                         {
109                                 return (this->operator==(leq) || this->operator<(leq));
110                         }
111                         
112                         inline bool operator>=(const Arbint & leq) const 
113                         {
114                                 return (this->operator==(leq) || this->operator>(leq));
115                         }
116                         inline bool operator>(const Arbint & grea) const
117                         {
118                                 return !(this->operator<=(grea));
119                         }
120                         inline Arbint operator>>(unsigned amount) const
121                         {
122                                 Arbint result(*this);
123                                 result >>= amount;
124                                 return result;
125                         }
126                         inline Arbint operator<<(unsigned amount) const
127                         {
128                                 Arbint result(*this);
129                                 result <<= amount;
130                                 return result;
131                         }
132                         bool IsZero() const;
133                         
134                         inline operator double() const 
135                         {
136                                 double acc = 0;
137                                 for(int i = m_digits.size()-1; i >= 0; --i)
138                                 {
139                                         acc += (double)m_digits[i];
140                                         acc *= (double)UINT64_MAX + 1.0;
141                                 }
142                                 if (m_sign) acc *= -1;
143                                 return acc;
144                         }
145                         inline operator int64_t() const {return AsDigit();}
146                         //inline operator int() const {return int(AsDigit());}
147                         
148                         unsigned Shrink();
149                         
150                         inline Arbint Abs() const {Arbint a(*this); a.m_sign = false; return a;}
151                 private:                
152                                 
153                         Arbint & AddBasic(const Arbint & add);
154                         Arbint & SubBasic(const Arbint & sub);
155                         
156                         bool GetBit(unsigned i) const;
157                         void BitClear(unsigned i);
158                         void BitSet(unsigned i);
159                         
160         
161                         std::vector<digit_t> m_digits;
162                         bool m_sign;
163                         void Zero();
164                         
165         };      
166
167
168
169 extern "C"
170 {
171         typedef uint64_t digit_t;
172         digit_t add_digits(digit_t * dst, digit_t * add, digit_t size);
173         digit_t sub_digits(digit_t * dst, digit_t * add, digit_t size);
174         digit_t mul_digits(digit_t * dst, digit_t mul, digit_t size);
175         digit_t div_digits(digit_t * dst, digit_t div, digit_t size, digit_t * rem);
176 }
177
178
179
180 }
181 #endif //_ARBINT_H

UCC git Repository :: git.ucc.asn.au