QtIotaBlock 0.4.1
Library with block types on IOTA
arith_uint256.h
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2022 The Bitcoin Core developers
3 
4 // modified version of https://github.com/bitcoin/bitcoin/blob/master/src/arith_uint256.h
5 
6 #pragma once
7 
8 #include <cstring>
9 #include <limits>
10 #include <stdexcept>
11 #include <stdint.h>
12 #include <string>
13 
15 {
16  public:
17  explicit uint_error(const std::string &str) : std::runtime_error(str)
18  {
19  }
20 };
21 
23 template <unsigned int BITS> class base_uint
24 {
25  protected:
26  static_assert(BITS / 32 > 0 && BITS % 32 == 0, "Template parameter BITS must be a positive multiple of 32.");
27  static constexpr int WIDTH = BITS / 32;
28  uint32_t pn[WIDTH];
29 
30  public:
32  {
33  for (int i = 0; i < WIDTH; i++)
34  pn[i] = 0;
35  }
36 
37  base_uint(const base_uint &b)
38  {
39  for (int i = 0; i < WIDTH; i++)
40  pn[i] = b.pn[i];
41  }
42 
44  {
45  for (int i = 0; i < WIDTH; i++)
46  pn[i] = b.pn[i];
47  return *this;
48  }
49 
50  base_uint(uint64_t b)
51  {
52  pn[0] = (unsigned int)b;
53  pn[1] = (unsigned int)(b >> 32);
54  for (int i = 2; i < WIDTH; i++)
55  pn[i] = 0;
56  }
57 
59  {
60  base_uint ret;
61  for (int i = 0; i < WIDTH; i++)
62  ret.pn[i] = ~pn[i];
63  return ret;
64  }
65 
67  {
68  base_uint ret;
69  for (int i = 0; i < WIDTH; i++)
70  ret.pn[i] = ~pn[i];
71  ++ret;
72  return ret;
73  }
74 
75  double getdouble() const;
76 
77  base_uint &operator=(uint64_t b)
78  {
79  pn[0] = (unsigned int)b;
80  pn[1] = (unsigned int)(b >> 32);
81  for (int i = 2; i < WIDTH; i++)
82  pn[i] = 0;
83  return *this;
84  }
85 
87  {
88  for (int i = 0; i < WIDTH; i++)
89  pn[i] ^= b.pn[i];
90  return *this;
91  }
92 
94  {
95  for (int i = 0; i < WIDTH; i++)
96  pn[i] &= b.pn[i];
97  return *this;
98  }
99 
101  {
102  for (int i = 0; i < WIDTH; i++)
103  pn[i] |= b.pn[i];
104  return *this;
105  }
106 
107  base_uint &operator^=(uint64_t b)
108  {
109  pn[0] ^= (unsigned int)b;
110  pn[1] ^= (unsigned int)(b >> 32);
111  return *this;
112  }
113 
114  base_uint &operator|=(uint64_t b)
115  {
116  pn[0] |= (unsigned int)b;
117  pn[1] |= (unsigned int)(b >> 32);
118  return *this;
119  }
120 
121  base_uint &operator<<=(unsigned int shift);
122  base_uint &operator>>=(unsigned int shift);
123 
125  {
126  uint64_t carry = 0;
127  for (int i = 0; i < WIDTH; i++)
128  {
129  uint64_t n = carry + pn[i] + b.pn[i];
130  pn[i] = n & 0xffffffff;
131  carry = n >> 32;
132  }
133  return *this;
134  }
135 
137  {
138  *this += -b;
139  return *this;
140  }
141 
142  base_uint &operator+=(uint64_t b64)
143  {
144  base_uint b;
145  b = b64;
146  *this += b;
147  return *this;
148  }
149 
150  base_uint &operator-=(uint64_t b64)
151  {
152  base_uint b;
153  b = b64;
154  *this += -b;
155  return *this;
156  }
157 
158  base_uint &operator*=(uint32_t b32);
159  base_uint &operator*=(const base_uint &b);
160  base_uint &operator/=(const base_uint &b);
161 
163  {
164  // prefix operator
165  int i = 0;
166  while (i < WIDTH && ++pn[i] == 0)
167  i++;
168  return *this;
169  }
170 
172  {
173  // postfix operator
174  const base_uint ret = *this;
175  ++(*this);
176  return ret;
177  }
178 
180  {
181  // prefix operator
182  int i = 0;
183  while (i < WIDTH && --pn[i] == std::numeric_limits<uint32_t>::max())
184  i++;
185  return *this;
186  }
187 
189  {
190  // postfix operator
191  const base_uint ret = *this;
192  --(*this);
193  return ret;
194  }
195 
196  int CompareTo(const base_uint &b) const;
197  bool EqualTo(uint64_t b) const;
198 
199  friend inline base_uint operator+(const base_uint &a, const base_uint &b)
200  {
201  return base_uint(a) += b;
202  }
203  friend inline base_uint operator-(const base_uint &a, const base_uint &b)
204  {
205  return base_uint(a) -= b;
206  }
207  friend inline base_uint operator*(const base_uint &a, const base_uint &b)
208  {
209  return base_uint(a) *= b;
210  }
211  friend inline base_uint operator/(const base_uint &a, const base_uint &b)
212  {
213  return base_uint(a) /= b;
214  }
215  friend inline base_uint operator|(const base_uint &a, const base_uint &b)
216  {
217  return base_uint(a) |= b;
218  }
219  friend inline base_uint operator&(const base_uint &a, const base_uint &b)
220  {
221  return base_uint(a) &= b;
222  }
223  friend inline base_uint operator^(const base_uint &a, const base_uint &b)
224  {
225  return base_uint(a) ^= b;
226  }
227  friend inline base_uint operator>>(const base_uint &a, int shift)
228  {
229  return base_uint(a) >>= shift;
230  }
231  friend inline base_uint operator<<(const base_uint &a, int shift)
232  {
233  return base_uint(a) <<= shift;
234  }
235  friend inline base_uint operator*(const base_uint &a, uint32_t b)
236  {
237  return base_uint(a) *= b;
238  }
239  friend inline bool operator==(const base_uint &a, const base_uint &b)
240  {
241  return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0;
242  }
243  friend inline bool operator!=(const base_uint &a, const base_uint &b)
244  {
245  return memcmp(a.pn, b.pn, sizeof(a.pn)) != 0;
246  }
247  friend inline bool operator>(const base_uint &a, const base_uint &b)
248  {
249  return a.CompareTo(b) > 0;
250  }
251  friend inline bool operator<(const base_uint &a, const base_uint &b)
252  {
253  return a.CompareTo(b) < 0;
254  }
255  friend inline bool operator>=(const base_uint &a, const base_uint &b)
256  {
257  return a.CompareTo(b) >= 0;
258  }
259  friend inline bool operator<=(const base_uint &a, const base_uint &b)
260  {
261  return a.CompareTo(b) <= 0;
262  }
263  friend inline bool operator==(const base_uint &a, uint64_t b)
264  {
265  return a.EqualTo(b);
266  }
267  friend inline bool operator!=(const base_uint &a, uint64_t b)
268  {
269  return !a.EqualTo(b);
270  }
271 
272  unsigned int size() const
273  {
274  return sizeof(pn);
275  }
276 
281  unsigned int bits() const;
282 
283  uint64_t GetLow64() const
284  {
285  static_assert(WIDTH >= 2, "Assertion WIDTH >= 2 failed (WIDTH = BITS / 32). BITS is a template parameter.");
286  return pn[0] | (uint64_t)pn[1] << 32;
287  }
288 };
Definition: arith_uint256.h:24
base_uint & operator=(const base_uint &b)
Definition: arith_uint256.h:43
base_uint operator~() const
Definition: arith_uint256.h:58
uint32_t pn[WIDTH]
Definition: arith_uint256.h:28
base_uint & operator=(uint64_t b)
Definition: arith_uint256.h:77
int CompareTo(const base_uint &b) const
Definition: arith_uint256.cpp:97
base_uint & operator+=(uint64_t b64)
Definition: arith_uint256.h:142
base_uint operator--(int)
Definition: arith_uint256.h:188
unsigned int size() const
Definition: arith_uint256.h:272
base_uint(uint64_t b)
Definition: arith_uint256.h:50
base_uint & operator--()
Definition: arith_uint256.h:179
friend bool operator!=(const base_uint &a, const base_uint &b)
Definition: arith_uint256.h:243
base_uint & operator^=(uint64_t b)
Definition: arith_uint256.h:107
base_uint & operator>>=(unsigned int shift)
Definition: arith_uint256.cpp:24
base_uint & operator++()
Definition: arith_uint256.h:162
friend base_uint operator-(const base_uint &a, const base_uint &b)
Definition: arith_uint256.h:203
base_uint(const base_uint &b)
Definition: arith_uint256.h:37
friend base_uint operator*(const base_uint &a, const base_uint &b)
Definition: arith_uint256.h:207
static constexpr int WIDTH
Definition: arith_uint256.h:27
base_uint & operator&=(const base_uint &b)
Definition: arith_uint256.h:93
friend base_uint operator<<(const base_uint &a, int shift)
Definition: arith_uint256.h:231
friend base_uint operator&(const base_uint &a, const base_uint &b)
Definition: arith_uint256.h:219
friend bool operator<(const base_uint &a, const base_uint &b)
Definition: arith_uint256.h:251
base_uint & operator-=(const base_uint &b)
Definition: arith_uint256.h:136
base_uint & operator+=(const base_uint &b)
Definition: arith_uint256.h:124
friend bool operator==(const base_uint &a, uint64_t b)
Definition: arith_uint256.h:263
base_uint operator-() const
Definition: arith_uint256.h:66
friend base_uint operator>>(const base_uint &a, int shift)
Definition: arith_uint256.h:227
friend bool operator>=(const base_uint &a, const base_uint &b)
Definition: arith_uint256.h:255
base_uint & operator*=(uint32_t b32)
Definition: arith_uint256.cpp:41
friend base_uint operator|(const base_uint &a, const base_uint &b)
Definition: arith_uint256.h:215
bool EqualTo(uint64_t b) const
Definition: arith_uint256.cpp:109
friend base_uint operator*(const base_uint &a, uint32_t b)
Definition: arith_uint256.h:235
friend bool operator==(const base_uint &a, const base_uint &b)
Definition: arith_uint256.h:239
base_uint()
Definition: arith_uint256.h:31
base_uint & operator|=(const base_uint &b)
Definition: arith_uint256.h:100
base_uint & operator-=(uint64_t b64)
Definition: arith_uint256.h:150
friend bool operator!=(const base_uint &a, uint64_t b)
Definition: arith_uint256.h:267
friend base_uint operator/(const base_uint &a, const base_uint &b)
Definition: arith_uint256.h:211
friend base_uint operator^(const base_uint &a, const base_uint &b)
Definition: arith_uint256.h:223
friend bool operator>(const base_uint &a, const base_uint &b)
Definition: arith_uint256.h:247
friend bool operator<=(const base_uint &a, const base_uint &b)
Definition: arith_uint256.h:259
base_uint & operator|=(uint64_t b)
Definition: arith_uint256.h:114
double getdouble() const
Definition: arith_uint256.cpp:123
base_uint & operator<<=(unsigned int shift)
Definition: arith_uint256.cpp:7
base_uint operator++(int)
Definition: arith_uint256.h:171
base_uint & operator^=(const base_uint &b)
Definition: arith_uint256.h:86
base_uint & operator/=(const base_uint &b)
Definition: arith_uint256.cpp:70
uint64_t GetLow64() const
Definition: arith_uint256.h:283
friend base_uint operator+(const base_uint &a, const base_uint &b)
Definition: arith_uint256.h:199
unsigned int bits() const
Definition: arith_uint256.cpp:134
Definition: arith_uint256.h:15
uint_error(const std::string &str)
Definition: arith_uint256.h:17