Bitcoin Core 31.99.0
P2P Digital Currency
arith_uint256.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Copyright (c) 2009-present 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#include <util/overflow.h>
11
12#include <cassert>
13
14template <unsigned int BITS>
16{
17 base_uint<BITS> a(*this);
18 for (int i = 0; i < WIDTH; i++)
19 pn[i] = 0;
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 if (i + k < WIDTH)
26 pn[i + k] |= (a.pn[i] << shift);
27 }
28 return *this;
29}
30
31template <unsigned int BITS>
33{
34 base_uint<BITS> a(*this);
35 for (int i = 0; i < WIDTH; i++)
36 pn[i] = 0;
37 int k = shift / 32;
38 shift = shift % 32;
39 for (int i = 0; i < WIDTH; i++) {
40 if (i - k - 1 >= 0 && shift != 0)
41 pn[i - k - 1] |= (a.pn[i] << (32 - shift));
42 if (i - k >= 0)
43 pn[i - k] |= (a.pn[i] >> shift);
44 }
45 return *this;
46}
47
48template <unsigned int BITS>
50{
51 uint64_t carry = 0;
52 for (int i = 0; i < WIDTH; i++) {
53 uint64_t n = carry + (uint64_t)b32 * pn[i];
54 pn[i] = n & 0xffffffff;
55 carry = n >> 32;
56 }
57 return *this;
58}
59
60template <unsigned int BITS>
62{
64 for (int j = 0; j < WIDTH; j++) {
65 uint64_t carry = 0;
66 for (int i = 0; i + j < WIDTH; i++) {
67 uint64_t n = carry + a.pn[i + j] + (uint64_t)pn[j] * b.pn[i];
68 a.pn[i + j] = n & 0xffffffff;
69 carry = n >> 32;
70 }
71 }
72 *this = a;
73 return *this;
74}
75
76template <unsigned int BITS>
78{
79 base_uint<BITS> div = b; // make a copy, so we can shift.
80 base_uint<BITS> num = *this; // make a copy, so we can subtract.
81 *this = 0; // the quotient.
82 int num_bits = num.bits();
83 int div_bits = div.bits();
84 if (div_bits == 0)
85 throw uint_error("Division by zero");
86 if (div_bits > num_bits) // the result is certainly 0.
87 return *this;
88 int shift = num_bits - div_bits;
89 div <<= shift; // shift so that div and num align.
90 while (shift >= 0) {
91 if (num >= div) {
92 num -= div;
93 pn[shift / 32] |= (1U << (shift & 31)); // set a bit of the result.
94 }
95 div >>= 1; // shift back.
96 shift--;
97 }
98 // num now contains the remainder of the division.
99 return *this;
100}
101
102template <unsigned int BITS>
104{
105 for (int i = WIDTH - 1; i >= 0; i--) {
106 if (pn[i] < b.pn[i])
107 return -1;
108 if (pn[i] > b.pn[i])
109 return 1;
110 }
111 return 0;
112}
113
114template <unsigned int BITS>
115bool base_uint<BITS>::EqualTo(uint64_t b) const
116{
117 for (int i = WIDTH - 1; i >= 2; i--) {
118 if (pn[i])
119 return false;
120 }
121 if (pn[1] != (b >> 32))
122 return false;
123 if (pn[0] != (b & 0xfffffffful))
124 return false;
125 return true;
126}
127
128template <unsigned int BITS>
130{
131 double ret = 0.0;
132 double fact = 1.0;
133 for (int i = 0; i < WIDTH; i++) {
134 ret += fact * pn[i];
135 fact *= 4294967296.0;
136 }
137 return ret;
138}
139
140template <unsigned int BITS>
141std::string base_uint<BITS>::GetHex() const
142{
144 for (int x = 0; x < this->WIDTH; ++x) {
145 WriteLE32(b.begin() + x*4, this->pn[x]);
146 }
147 return b.GetHex();
148}
149
150template <unsigned int BITS>
151std::string base_uint<BITS>::ToString() const
153 return GetHex();
154}
155
156template <unsigned int BITS>
157unsigned int base_uint<BITS>::bits() const
158{
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 return 32 * pos + 1;
166 }
167 }
168 return 0;
169}
170
171// Explicit instantiations for base_uint<256>
172template class base_uint<256>;
173
174// This implementation directly uses shifts instead of going
175// through an intermediate MPI representation.
176arith_uint256& arith_uint256::SetCompact(uint32_t nCompact, bool* pfNegative, bool* pfOverflow)
177{
178 int nSize = nCompact >> 24;
179 uint32_t nWord = nCompact & 0x007fffff;
180 if (nSize <= 3) {
181 nWord >>= 8 * (3 - nSize);
182 *this = nWord;
183 } else {
184 *this = nWord;
185 *this <<= 8 * (nSize - 3);
186 }
187 if (pfNegative)
188 *pfNegative = nWord != 0 && (nCompact & 0x00800000) != 0;
189 if (pfOverflow)
190 *pfOverflow = nWord != 0 && ((nSize > 34) ||
191 (nWord > 0xff && nSize > 33) ||
192 (nWord > 0xffff && nSize > 32));
193 return *this;
194}
195
196uint32_t arith_uint256::GetCompact(bool fNegative) const
197{
198 int nSize = CeilDiv(bits(), 8u);
199 uint32_t nCompact = 0;
200 if (nSize <= 3) {
201 nCompact = GetLow64() << 8 * (3 - nSize);
202 } else {
203 arith_uint256 bn = *this >> 8 * (nSize - 3);
204 nCompact = bn.GetLow64();
205 }
206 // The 0x00800000 bit denotes the sign.
207 // Thus, if it is already set, divide the mantissa by 256 and increase the exponent.
208 if (nCompact & 0x00800000) {
209 nCompact >>= 8;
210 nSize++;
211 }
212 assert((nCompact & ~0x007fffffU) == 0);
213 assert(nSize < 256);
214 nCompact |= nSize << 24;
215 nCompact |= (fNegative && (nCompact & 0x007fffff) ? 0x00800000 : 0);
216 return nCompact;
217}
218
221 uint256 b;
222 for(int x=0; x<a.WIDTH; ++x)
223 WriteLE32(b.begin() + x*4, a.pn[x]);
224 return b;
225}
227{
229 for(int x=0; x<b.WIDTH; ++x)
230 b.pn[x] = ReadLE32(a.begin() + x*4);
231 return b;
232}
233
234// Explicit instantiations for base_uint<6144> (used in test/fuzz/muhash.cpp).
arith_uint256 UintToArith256(const uint256 &a)
uint256 ArithToUint256(const arith_uint256 &a)
int ret
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
Template base class for fixed-sized opaque blobs.
Definition: uint256.h:26
constexpr unsigned char * begin()
Definition: uint256.h:100
std::string GetHex() const
Definition: uint256.cpp:11
Template base class for unsigned big integers.
Definition: arith_uint256.h:26
base_uint & operator/=(const base_uint &b)
uint32_t pn[WIDTH]
Big integer represented with 32-bit digits, least-significant first.
Definition: arith_uint256.h:31
int CompareTo(const base_uint &b) const
Numeric ordering (unlike base_blob::Compare)
base_uint & operator>>=(unsigned int shift)
static constexpr int WIDTH
Definition: arith_uint256.h:29
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
Hex encoding of the number (with the most significant digits first).
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:195
void WriteLE32(B *ptr, uint32_t x)
Definition: common.h:50
uint32_t ReadLE32(const B *ptr)
Definition: common.h:27
constexpr auto CeilDiv(const Dividend dividend, const Divisor divisor)
Integer ceiling division (for unsigned values).
Definition: overflow.h:70
assert(!tx.IsCoinBase())