Bitcoin ABC 0.33.12
P2P Digital Currency
arith_uint256.cpp
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#include <arith_uint256.h>
7
8#include <crypto/common.h>
9#include <uint256.h>
10
11#include <cassert>
12#include <cmath>
13
14template <unsigned int BITS>
16 base_uint<BITS> a(*this);
17 for (int i = 0; i < WIDTH; i++) {
18 pn[i] = 0;
19 }
20 int k = shift / 32;
21 shift = shift % 32;
22 for (int i = 0; i < WIDTH; i++) {
23 if (i + k + 1 < WIDTH && shift != 0) {
24 pn[i + k + 1] |= (a.pn[i] >> (32 - shift));
25 }
26 if (i + k < WIDTH) {
27 pn[i + k] |= (a.pn[i] << shift);
28 }
29 }
30 return *this;
31}
32
33template <unsigned int BITS>
35 base_uint<BITS> a(*this);
36 for (int i = 0; i < WIDTH; i++) {
37 pn[i] = 0;
38 }
39 int k = shift / 32;
40 shift = shift % 32;
41 for (int i = 0; i < WIDTH; i++) {
42 if (i - k - 1 >= 0 && shift != 0) {
43 pn[i - k - 1] |= (a.pn[i] << (32 - shift));
44 }
45 if (i - k >= 0) {
46 pn[i - k] |= (a.pn[i] >> shift);
47 }
48 }
49 return *this;
50}
51
52template <unsigned int BITS>
54 uint64_t carry = 0;
55 for (int i = 0; i < WIDTH; i++) {
56 uint64_t n = carry + (uint64_t)b32 * pn[i];
57 pn[i] = n & 0xffffffff;
58 carry = n >> 32;
59 }
60 return *this;
61}
62
63template <unsigned int BITS>
66 for (int j = 0; j < WIDTH; j++) {
67 uint64_t carry = 0;
68 for (int i = 0; i + j < WIDTH; i++) {
69 uint64_t n = carry + a.pn[i + j] + (uint64_t)pn[j] * b.pn[i];
70 a.pn[i + j] = n & 0xffffffff;
71 carry = n >> 32;
72 }
73 }
74 *this = a;
75 return *this;
76}
77
78template <unsigned int BITS>
80 // make a copy, so we can shift.
81 base_uint<BITS> div = b;
82 // make a copy, so we can subtract.
83 base_uint<BITS> num = *this;
84 // the quotient.
85 *this = 0;
86 int num_bits = num.bits();
87 int div_bits = div.bits();
88 if (div_bits == 0) {
89 throw uint_error("Division by zero");
90 }
91 // the result is certainly 0.
92 if (div_bits > num_bits) {
93 return *this;
94 }
95 int shift = num_bits - div_bits;
96 // shift so that div and num align.
97 div <<= shift;
98 while (shift >= 0) {
99 if (num >= div) {
100 num -= div;
101 // set a bit of the result.
102 pn[shift / 32] |= (1U << (shift & 31));
103 }
104 // shift back.
105 div >>= 1;
106 shift--;
107 }
108 // num now contains the remainder of the division.
109 return *this;
110}
111
112template <unsigned int BITS>
114 for (int i = WIDTH - 1; i >= 0; i--) {
115 if (pn[i] < b.pn[i]) {
116 return -1;
117 }
118 if (pn[i] > b.pn[i]) {
119 return 1;
120 }
121 }
122 return 0;
123}
124
125template <unsigned int BITS> bool base_uint<BITS>::EqualTo(uint64_t b) const {
126 for (int i = WIDTH - 1; i >= 2; i--) {
127 if (pn[i]) {
128 return false;
131 if (pn[1] != (b >> 32)) {
132 return false;
133 }
134 if (pn[0] != (b & 0xfffffffful)) {
135 return false;
136 }
137 return true;
138}
139
140template <unsigned int BITS> double base_uint<BITS>::getdouble() const {
141 double ret = 0.0;
142 double fact = 1.0;
143 for (int i = 0; i < WIDTH; i++) {
144 ret += fact * pn[i];
145 fact *= 4294967296.0;
146 }
147 return ret;
148}
149
150template <unsigned int BITS> std::string base_uint<BITS>::GetHex() const {
151 return ArithToUint256(*this).GetHex();
152}
153
154template <unsigned int BITS> std::string base_uint<BITS>::ToString() const {
155 return (GetHex());
156}
157
158template <unsigned int BITS> unsigned int base_uint<BITS>::bits() const {
159 for (int pos = WIDTH - 1; pos >= 0; pos--) {
160 if (pn[pos]) {
161 for (int nbits = 31; nbits > 0; nbits--) {
162 if (pn[pos] & 1U << nbits) {
163 return 32 * pos + nbits + 1;
164 }
165 }
166 return 32 * pos + 1;
167 }
168 }
169 return 0;
170}
171
172// Explicit instantiations for base_uint<256>
173template base_uint<256> &base_uint<256>::operator<<=(unsigned int);
174template base_uint<256> &base_uint<256>::operator>>=(unsigned int);
175template base_uint<256> &base_uint<256>::operator*=(uint32_t b32);
178template int base_uint<256>::CompareTo(const base_uint<256> &) const;
179template bool base_uint<256>::EqualTo(uint64_t) const;
180template double base_uint<256>::getdouble() const;
181template std::string base_uint<256>::GetHex() const;
182template std::string base_uint<256>::ToString() const;
183template unsigned int base_uint<256>::bits() const;
184
185// This implementation directly uses shifts instead of going through an
186// intermediate MPI representation.
187arith_uint256 &arith_uint256::SetCompact(uint32_t nCompact, bool *pfNegative,
188 bool *pfOverflow) {
189 int nSize = nCompact >> 24;
190 uint32_t nWord = nCompact & 0x007fffff;
191 if (nSize <= 3) {
192 nWord >>= 8 * (3 - nSize);
193 *this = nWord;
194 } else {
195 *this = nWord;
196 *this <<= 8 * (nSize - 3);
198 if (pfNegative) {
199 *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;
200 }
201 if (pfOverflow) {
202 *pfOverflow =
203 nWord != 0 && ((nSize > 34) || (nWord > 0xff && nSize > 33) ||
204 (nWord > 0xffff && nSize > 32));
205 }
206 return *this;
207}
208
209uint32_t arith_uint256::GetCompact(bool fNegative) const {
210 int nSize = (bits() + 7) / 8;
211 uint32_t nCompact = 0;
212 if (nSize <= 3) {
213 nCompact = GetLow64() << 8 * (3 - nSize);
214 } else {
215 arith_uint256 bn = *this >> 8 * (nSize - 3);
216 nCompact = bn.GetLow64();
217 }
218 // The 0x00800000 bit denotes the sign.
219 // Thus, if it is already set, divide the mantissa by 256 and increase the
220 // exponent.
221 if (nCompact & 0x00800000) {
222 nCompact >>= 8;
223 nSize++;
224 }
225 assert((nCompact & ~0x007fffffU) == 0);
226 assert(nSize < 256);
227 nCompact |= nSize << 24;
228 nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
229 return nCompact;
230}
231
234 for (int i = b.WIDTH - 1; i >= 0; i--) {
235 const double fact = std::pow(4294967296.0, i);
236 b.pn[i] = uint32_t(d / fact);
237 d -= fact * b.pn[i];
238 }
239 return b;
240}
241
243 uint256 b;
244 for (int x = 0; x < a.WIDTH; ++x) {
245 WriteLE32(b.begin() + x * 4, a.pn[x]);
246 }
247 return b;
248}
251 for (int x = 0; x < b.WIDTH; ++x) {
252 b.pn[x] = ReadLE32(a.begin() + x * 4);
253 }
254 return b;
257// Explicit instantiations for base_uint<6144> (used in test/fuzz/muhash.cpp).
arith_uint256 UintToArith256(const uint256 &a)
uint256 ArithToUint256(const arith_uint256 &a)
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)
constexpr uint8_t * begin()
Definition: uint256.h:89
std::string GetHex() const
Definition: uint256.cpp:10
Template base class for unsigned big integers.
Definition: arith_uint256.h:23
base_uint & operator/=(const base_uint &b)
uint32_t pn[WIDTH]
Definition: arith_uint256.h:26
int CompareTo(const base_uint &b) const
base_uint & operator>>=(unsigned int shift)
static constexpr int WIDTH
Definition: arith_uint256.h:25
base_uint & operator*=(uint32_t b32)
bool EqualTo(uint64_t b) const
double getdouble() const
base_uint & operator<<=(unsigned int shift)
std::string ToString() const
uint64_t GetLow64() const
std::string GetHex() const
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:127
static void WriteLE32(uint8_t *ptr, uint32_t x)
Definition: common.h:36
static uint32_t ReadLE32(const uint8_t *ptr)
Definition: common.h:19
assert(!tx.IsCoinBase())