Bitcoin ABC 0.34.2
P2P Digital Currency
arith_uint256.h
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-2016 The Bitcoin Core developers
3// Distributed under the MIT software license, see the accompanying
4// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5
6#ifndef BITCOIN_ARITH_UINT256_H
7#define BITCOIN_ARITH_UINT256_H
8
9#include <compare>
10#include <cstdint>
11#include <cstring>
12#include <limits>
13#include <stdexcept>
14#include <string>
15
16class uint256;
17
18class uint_error : public std::runtime_error {
19public:
20 explicit uint_error(const std::string &str) : std::runtime_error(str) {}
21};
22
24template <unsigned int BITS> class base_uint {
25protected:
26 static constexpr int WIDTH = BITS / 32;
27 uint32_t pn[WIDTH];
28
29public:
31 static_assert(
32 BITS / 32 > 0 && BITS % 32 == 0,
33 "Template parameter BITS must be a positive multiple of 32.");
34
35 for (int i = 0; i < WIDTH; i++) {
36 pn[i] = 0;
37 }
38 }
39
40 base_uint(const base_uint &b) {
41 static_assert(
42 BITS / 32 > 0 && BITS % 32 == 0,
43 "Template parameter BITS must be a positive multiple of 32.");
44
45 for (int i = 0; i < WIDTH; i++) {
46 pn[i] = b.pn[i];
47 }
48 }
49
51 for (int i = 0; i < WIDTH; i++) {
52 pn[i] = b.pn[i];
53 }
54 return *this;
55 }
56
57 base_uint(uint64_t b) {
58 static_assert(
59 BITS / 32 > 0 && BITS % 32 == 0,
60 "Template parameter BITS must be a positive multiple of 32.");
61
62 pn[0] = (unsigned int)b;
63 pn[1] = (unsigned int)(b >> 32);
64 for (int i = 2; i < WIDTH; i++) {
65 pn[i] = 0;
66 }
67 }
68
70 base_uint ret;
71 for (int i = 0; i < WIDTH; i++) {
72 ret.pn[i] = ~pn[i];
73 }
74 return ret;
75 }
76
78 base_uint ret;
79 for (int i = 0; i < WIDTH; i++) {
80 ret.pn[i] = ~pn[i];
81 }
82 ++ret;
83 return ret;
84 }
85
86 double getdouble() const;
87
88 base_uint &operator=(uint64_t b) {
89 pn[0] = (unsigned int)b;
90 pn[1] = (unsigned int)(b >> 32);
91 for (int i = 2; i < WIDTH; i++) {
92 pn[i] = 0;
93 }
94 return *this;
95 }
96
98 for (int i = 0; i < WIDTH; i++) {
99 pn[i] ^= b.pn[i];
100 }
101 return *this;
102 }
103
105 for (int i = 0; i < WIDTH; i++) {
106 pn[i] &= b.pn[i];
107 }
108 return *this;
109 }
110
112 for (int i = 0; i < WIDTH; i++) {
113 pn[i] |= b.pn[i];
114 }
115 return *this;
116 }
117
118 base_uint &operator^=(uint64_t b) {
119 pn[0] ^= (unsigned int)b;
120 pn[1] ^= (unsigned int)(b >> 32);
121 return *this;
122 }
123
124 base_uint &operator|=(uint64_t b) {
125 pn[0] |= (unsigned int)b;
126 pn[1] |= (unsigned int)(b >> 32);
127 return *this;
128 }
129
130 base_uint &operator<<=(unsigned int shift);
131 base_uint &operator>>=(unsigned int shift);
132
134 uint64_t carry = 0;
135 for (int i = 0; i < WIDTH; i++) {
136 uint64_t n = carry + pn[i] + b.pn[i];
137 pn[i] = n & 0xffffffff;
138 carry = n >> 32;
139 }
140 return *this;
141 }
142
144 *this += -b;
145 return *this;
146 }
147
148 base_uint &operator+=(uint64_t b64) {
149 base_uint b;
150 b = b64;
151 *this += b;
152 return *this;
153 }
154
155 base_uint &operator-=(uint64_t b64) {
156 base_uint b;
157 b = b64;
158 *this += -b;
159 return *this;
160 }
161
162 base_uint &operator*=(uint32_t b32);
163 base_uint &operator*=(const base_uint &b);
164 base_uint &operator/=(const base_uint &b);
165
167 // prefix operator
168 int i = 0;
169 while (i < WIDTH && ++pn[i] == 0) {
170 i++;
171 }
172 return *this;
173 }
174
176 // postfix operator
177 const base_uint ret = *this;
178 ++(*this);
179 return ret;
180 }
181
183 // prefix operator
184 int i = 0;
185 while (i < WIDTH && --pn[i] == std::numeric_limits<uint32_t>::max()) {
186 i++;
187 }
188 return *this;
189 }
190
192 // postfix operator
193 const base_uint ret = *this;
194 --(*this);
195 return ret;
196 }
197
198 int CompareTo(const base_uint &b) const;
199 bool EqualTo(uint64_t b) const;
200
201 friend inline base_uint operator+(const base_uint &a, const base_uint &b) {
202 return base_uint(a) += b;
203 }
204 friend inline base_uint operator-(const base_uint &a, const base_uint &b) {
205 return base_uint(a) -= b;
206 }
207 friend inline base_uint operator*(const base_uint &a, const base_uint &b) {
208 return base_uint(a) *= b;
209 }
210 friend inline base_uint operator/(const base_uint &a, const base_uint &b) {
211 return base_uint(a) /= b;
212 }
213 friend inline base_uint operator|(const base_uint &a, const base_uint &b) {
214 return base_uint(a) |= b;
215 }
216 friend inline base_uint operator&(const base_uint &a, const base_uint &b) {
217 return base_uint(a) &= b;
218 }
219 friend inline base_uint operator^(const base_uint &a, const base_uint &b) {
220 return base_uint(a) ^= b;
221 }
222 friend inline base_uint operator>>(const base_uint &a, int shift) {
223 return base_uint(a) >>= shift;
224 }
225 friend inline base_uint operator<<(const base_uint &a, int shift) {
226 return base_uint(a) <<= shift;
227 }
228 friend inline base_uint operator*(const base_uint &a, uint32_t b) {
229 return base_uint(a) *= b;
230 }
231 friend inline bool operator==(const base_uint &a, const base_uint &b) {
232 return memcmp(a.pn, b.pn, sizeof(a.pn)) == 0;
233 }
234 friend inline std::strong_ordering operator<=>(const base_uint &a,
235 const base_uint &b) {
236 return a.CompareTo(b) <=> 0;
237 }
238 friend inline bool operator==(const base_uint &a, uint64_t b) {
239 return a.EqualTo(b);
240 }
241
242 std::string GetHex() const;
243 std::string ToString() const;
244
245 unsigned int size() const { return sizeof(pn); }
246
251 unsigned int bits() const;
252
253 uint64_t GetLow64() const {
254 static_assert(WIDTH >= 2, "Assertion WIDTH >= 2 failed (WIDTH = BITS / "
255 "32). BITS is a template parameter.");
256 return pn[0] | uint64_t(pn[1]) << 32;
257 }
258};
259
261class arith_uint256 : public base_uint<256> {
262public:
263 arith_uint256() = default;
265 arith_uint256(uint64_t b) : base_uint<256>(b) {}
266
285 arith_uint256 &SetCompact(uint32_t nCompact, bool *pfNegative = nullptr,
286 bool *pfOverflow = nullptr);
287 uint32_t GetCompact(bool fNegative = false) const;
288
289 static arith_uint256 fromDouble(double d);
290
291 friend uint256 ArithToUint256(const arith_uint256 &);
292 friend arith_uint256 UintToArith256(const uint256 &);
293};
294
297
298#endif // BITCOIN_ARITH_UINT256_H
arith_uint256 UintToArith256(const uint256 &)
uint256 ArithToUint256(const arith_uint256 &)
256-bit unsigned big integer.
arith_uint256 & SetCompact(uint32_t nCompact, bool *pfNegative=nullptr, bool *pfOverflow=nullptr)
The "compact" format is a representation of a whole number N using an unsigned 32bit number similar t...
uint32_t GetCompact(bool fNegative=false) const
static arith_uint256 fromDouble(double d)
arith_uint256()=default
arith_uint256(uint64_t b)
arith_uint256(const base_uint< 256 > &b)
friend arith_uint256 UintToArith256(const uint256 &)
friend uint256 ArithToUint256(const arith_uint256 &)
Template base class for unsigned big integers.
Definition: arith_uint256.h:24
base_uint & operator/=(const base_uint &b)
base_uint operator~() const
Definition: arith_uint256.h:69
uint32_t pn[WIDTH]
Definition: arith_uint256.h:27
int CompareTo(const base_uint &b) const
base_uint operator--(int)
unsigned int size() const
base_uint(uint64_t b)
Definition: arith_uint256.h:57
base_uint & operator^=(const base_uint &b)
Definition: arith_uint256.h:97
base_uint & operator|=(uint64_t b)
base_uint & operator+=(uint64_t b64)
base_uint & operator>>=(unsigned int shift)
base_uint & operator++()
base_uint & operator--()
base_uint & operator=(uint64_t b)
Definition: arith_uint256.h:88
friend base_uint operator-(const base_uint &a, const base_uint &b)
base_uint(const base_uint &b)
Definition: arith_uint256.h:40
friend base_uint operator*(const base_uint &a, const base_uint &b)
static constexpr int WIDTH
Definition: arith_uint256.h:26
friend base_uint operator<<(const base_uint &a, int shift)
friend std::strong_ordering operator<=>(const base_uint &a, const base_uint &b)
base_uint & operator|=(const base_uint &b)
friend base_uint operator&(const base_uint &a, const base_uint &b)
base_uint & operator-=(uint64_t b64)
friend bool operator==(const base_uint &a, uint64_t b)
base_uint & operator^=(uint64_t b)
base_uint operator-() const
Definition: arith_uint256.h:77
friend base_uint operator>>(const base_uint &a, int shift)
base_uint & operator*=(uint32_t b32)
friend base_uint operator|(const base_uint &a, const base_uint &b)
bool EqualTo(uint64_t b) const
friend base_uint operator*(const base_uint &a, uint32_t b)
base_uint & operator&=(const base_uint &b)
friend bool operator==(const base_uint &a, const base_uint &b)
friend base_uint operator/(const base_uint &a, const base_uint &b)
friend base_uint operator^(const base_uint &a, const base_uint &b)
double getdouble() const
base_uint & operator<<=(unsigned int shift)
std::string ToString() const
base_uint operator++(int)
base_uint & operator+=(const base_uint &b)
uint64_t GetLow64() const
base_uint & operator=(const base_uint &b)
Definition: arith_uint256.h:50
std::string GetHex() const
base_uint & operator-=(const base_uint &b)
friend base_uint operator+(const base_uint &a, const base_uint &b)
unsigned int bits() const
Returns the position of the highest bit set plus one, or zero if the value is zero.
256-bit opaque blob.
Definition: uint256.h:199
uint_error(const std::string &str)
Definition: arith_uint256.h:20
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:259