mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-11-12 15:09:59 +01:00
Add multiplication and division to uint160/uint256
This commit is contained in:
@@ -222,6 +222,57 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
base_uint& operator*=(uint32_t b32)
|
||||
{
|
||||
uint64_t carry = 0;
|
||||
for (int i = 0; i < WIDTH; i++)
|
||||
{
|
||||
uint64_t n = carry + (uint64_t)b32 * pn[i];
|
||||
pn[i] = n & 0xffffffff;
|
||||
carry = n >> 32;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
base_uint& operator*=(const base_uint& b)
|
||||
{
|
||||
base_uint a = *this;
|
||||
*this = 0;
|
||||
for (int j = 0; j < WIDTH; j++) {
|
||||
uint64_t carry = 0;
|
||||
for (int i = 0; i + j < WIDTH; i++) {
|
||||
uint64_t n = carry + pn[i + j] + (uint64_t)a.pn[j] * b.pn[i];
|
||||
pn[i + j] = n & 0xffffffff;
|
||||
carry = n >> 32;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
base_uint& operator/=(const base_uint& b)
|
||||
{
|
||||
base_uint div = b; // make a copy, so we can shift.
|
||||
base_uint num = *this; // make a copy, so we can subtract.
|
||||
*this = 0; // the quotient.
|
||||
int num_bits = num.bits();
|
||||
int div_bits = div.bits();
|
||||
if (div_bits == 0)
|
||||
throw uint_error("Division by zero");
|
||||
if (div_bits > num_bits) // the result is certainly 0.
|
||||
return *this;
|
||||
int shift = num_bits - div_bits;
|
||||
div <<= shift; // shift so that div and nun align.
|
||||
while (shift >= 0) {
|
||||
if (num >= div) {
|
||||
num -= div;
|
||||
pn[shift / 32] |= (1 << (shift & 31)); // set a bit of the result.
|
||||
}
|
||||
div >>= 1; // shift back.
|
||||
shift--;
|
||||
}
|
||||
// num now contains the remainder of the division.
|
||||
return *this;
|
||||
}
|
||||
|
||||
base_uint& operator++()
|
||||
{
|
||||
@@ -338,11 +389,14 @@ public:
|
||||
|
||||
friend inline const base_uint operator+(const base_uint& a, const base_uint& b) { return base_uint(a) += b; }
|
||||
friend inline const base_uint operator-(const base_uint& a, const base_uint& b) { return base_uint(a) -= b; }
|
||||
friend inline const base_uint operator*(const base_uint& a, const base_uint& b) { return base_uint(a) *= b; }
|
||||
friend inline const base_uint operator/(const base_uint& a, const base_uint& b) { return base_uint(a) /= b; }
|
||||
friend inline const base_uint operator|(const base_uint& a, const base_uint& b) { return base_uint(a) |= b; }
|
||||
friend inline const base_uint operator&(const base_uint& a, const base_uint& b) { return base_uint(a) &= b; }
|
||||
friend inline const base_uint operator^(const base_uint& a, const base_uint& b) { return base_uint(a) ^= b; }
|
||||
friend inline const base_uint operator>>(const base_uint& a, int shift) { return base_uint(a) >>= shift; }
|
||||
friend inline const base_uint operator<<(const base_uint& a, int shift) { return base_uint(a) <<= shift; }
|
||||
friend inline const base_uint operator*(const base_uint& a, uint32_t b) { return base_uint(a) *= b; }
|
||||
|
||||
std::string GetHex() const
|
||||
{
|
||||
@@ -417,6 +471,22 @@ public:
|
||||
return sizeof(pn);
|
||||
}
|
||||
|
||||
// Returns the position of the highest bit set plus one, or zero if the
|
||||
// value is zero.
|
||||
unsigned int bits() const
|
||||
{
|
||||
for (int pos = WIDTH-1; pos >= 0; pos--) {
|
||||
if (pn[pos]) {
|
||||
for (int bits = 31; bits > 0; bits--) {
|
||||
if (pn[pos] & 1<<bits)
|
||||
return 32*pos + bits + 1;
|
||||
}
|
||||
return 32*pos + 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t GetLow64() const
|
||||
{
|
||||
assert(WIDTH >= 2);
|
||||
|
||||
Reference in New Issue
Block a user