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