16 uint64_t top[4] = { value1._upper >> 32, value1._upper & 0xFFFFFFFF, value1._lower >> 32, value1._lower & 0xFFFFFFFF };
17 uint64_t bottom[4] = { value2._upper >> 32, value2._upper & 0xFFFFFFFF, value2._lower >> 32, value2._lower & 0xFFFFFFFF };
18 uint64_t products[4][4];
21 for (
int y = 3; y > -1; --y)
22 for (
int x = 3; x > -1; --x)
23 products[3 - x][y] = top[x] * bottom[y];
26 uint64_t fourth32 = (products[0][3] & 0xFFFFFFFF);
27 uint64_t third32 = (products[0][2] & 0xFFFFFFFF) + (products[0][3] >> 32);
28 uint64_t second32 = (products[0][1] & 0xFFFFFFFF) + (products[0][2] >> 32);
29 uint64_t first32 = (products[0][0] & 0xFFFFFFFF) + (products[0][1] >> 32);
32 third32 += (products[1][3] & 0xFFFFFFFF);
33 second32 += (products[1][2] & 0xFFFFFFFF) + (products[1][3] >> 32);
34 first32 += (products[1][1] & 0xFFFFFFFF) + (products[1][2] >> 32);
37 second32 += (products[2][3] & 0xFFFFFFFF);
38 first32 += (products[2][2] & 0xFFFFFFFF) + (products[2][3] >> 32);
41 first32 += (products[3][3] & 0xFFFFFFFF);
44 third32 += fourth32 >> 32;
45 second32 += third32 >> 32;
46 first32 += second32 >> 32;
49 fourth32 &= 0xFFFFFFFF;
50 third32 &= 0xFFFFFFFF;
51 second32 &= 0xFFFFFFFF;
52 first32 &= 0xFFFFFFFF;
55 return uint128_t((first32 << 32) | second32, (third32 << 32) | fourth32);
60 const uint64_t shift = value2._lower;
62 if (((
bool)value2._upper) || (shift >= 128))
69 return uint128_t((value1._upper << shift) + (value1._lower >> (64 - shift)), value1._lower << shift);
70 else if ((128 > shift) && (shift > 64))
71 return uint128_t(value1._lower << (shift - 64), 0);
78 const uint64_t shift = value2._lower;
80 if (((
bool)value2._upper) || (shift >= 128))
87 return uint128_t(value1._upper >> shift, (value1._upper << (64 - shift)) + (value1._lower >> shift));
88 else if ((128 > shift) && (shift > 64))
89 return uint128_t(0, (value1._upper >> (shift - 64)));
101 uint64_t
upper = _upper;
110 uint64_t
lower = _lower;
123 if ((base < 2) || (base > 16))
124 throw std::invalid_argument(
"Base must be in the range [2, 16]");
132 std::pair<uint128_t, uint128_t> qr(*
this, 0);
136 out =
"0123456789abcdef"[(uint8_t)qr.second] + out;
137 }
while (qr.first != 0);
140 if (out.size() < length)
141 out = std::string(length - out.size(),
'0') + out;
148 if ((base < 2) || (base > 16))
149 throw std::invalid_argument(
"Base must be in the range [2, 16]");
157 std::pair<uint128_t, uint128_t> qr(*
this, 0);
161 out = L
"0123456789abcdef"[(uint8_t)qr.second] + out;
162 }
while (qr.first != 0);
165 if (out.size() < length)
166 out = std::wstring(length - out.size(), L
'0') + out;
174 throw std::domain_error(
"Division by 0");
176 return std::pair<uint128_t, uint128_t>(x, 0);
178 return std::pair<uint128_t, uint128_t>(1, 0);
179 else if ((x == 0) || (x < y))
180 return std::pair<uint128_t, uint128_t>(0, x);
182 std::pair<uint128_t, uint128_t> result(0, 0);
184 for (
size_t i = x.
bits(); i > 0; --i)
189 if ((x >> (i - 1u)) & 1)
192 if (result.second >= y)
Unsigned 128-bit integer type.
static std::pair< uint128_t, uint128_t > divmod(const uint128_t &x, const uint128_t &y)
Calculate quotient and remainder when dividing X by Y.
size_t bits() const noexcept
Get the count of bits.
std::wstring wstring(size_t base=10, size_t length=0) const
Get wide string from the current 128-bit integer.
uint64_t lower() const noexcept
Get the lower part of the 128-bit integer.
uint64_t upper() const noexcept
Get the upper part of the 128-bit integer.
std::string string(size_t base=10, size_t length=0) const
Get string from the current 128-bit integer.
C++ Common project definitions.
std::ostream & operator<<(std::ostream &os, const uint128_t &value)
uint128_t operator*(const uint128_t &value1, const uint128_t &value2) noexcept
uint128_t operator>>(const uint128_t &value1, const uint128_t &value2) noexcept
Unsigned 128-bit integer type definition.