10 #ifndef TEUCHOS_BIG_UINT_HPP
11 #define TEUCHOS_BIG_UINT_HPP
23 BigUInt<n>::BigUInt() {}
26 BigUInt<n>::BigUInt(std::uint64_t v) {
27 for (
int i = 2; i < n; ++i) x[i] = 0;
28 if (n > 1) x[1] = std::uint32_t(v >> 32);
29 x[0] = std::uint32_t(v);
33 BigUInt<n>::BigUInt(std::string
const& s) : BigUInt(std::uint32_t(0)) {
41 BigUInt<n>::operator bool() const noexcept {
42 for (
int i = 0; i < n; ++i)
if (x[i])
return true;
47 std::uint32_t& BigUInt<n>::operator[](
int i) {
return x[i]; }
50 std::uint32_t
const& BigUInt<n>::operator[](
int i)
const {
return x[i]; }
53 BigUInt<n>& BigUInt<n>::operator+=(std::uint32_t b) {
54 std::uint32_t carry = b;
55 for (
int i = 0; i < n; ++i) {
56 std::uint64_t ax = x[i];
57 auto cx = ax + std::uint64_t(carry);
58 carry = std::uint32_t(cx >> 32);
59 x[i] = std::uint32_t(cx);
65 BigUInt<n>& BigUInt<n>::operator+=(BigUInt<n>
const& b) {
66 std::uint32_t carry = 0;
67 for (
int i = 0; i < n; ++i) {
68 std::uint64_t ax = x[i];
69 std::uint64_t bx = b[i];
70 auto cx = ax + bx + std::uint64_t(carry);
71 carry = std::uint32_t(cx >> 32);
72 x[i] = std::uint32_t(cx);
78 BigUInt<n>& BigUInt<n>::operator-=(std::uint32_t b) {
79 std::int64_t carry = b;
80 for (
int i = 0; i < n; ++i) {
81 std::int64_t ax = x[i];
85 cx += std::int64_t(1) << 32;
89 x[i] = std::uint32_t(cx);
95 BigUInt<n>& BigUInt<n>::operator-=(BigUInt<n>
const& b) {
96 std::int64_t carry = 0;
97 for (
int i = 0; i < n; ++i) {
98 std::int64_t ax = x[i];
99 std::int64_t bx = b[i];
100 auto cx = ax - bx - carry;
103 cx += std::int64_t(1) << 32;
107 x[i] = std::uint32_t(cx);
113 BigUInt<n>& BigUInt<n>::operator*=(std::uint32_t b) {
114 std::uint32_t carry = 0;
115 for (
int i = 0; i < n; ++i) {
116 std::uint64_t ax = x[i];
117 auto cx = (ax * std::uint64_t(b)) + std::uint64_t(carry);
118 carry = std::uint32_t(cx >> 32);
119 x[i] = std::uint32_t(cx);
125 BigUInt<n>& BigUInt<n>::operator<<=(std::uint32_t b) {
126 auto ndigits = b / 32;
127 auto nbits = b - (ndigits * 32);
128 for (
int i = n - 1; i >= 0; --i) {
129 std::uint32_t xi = 0;
130 if (i >=
int(ndigits)) {
131 xi = x[i - ndigits] << nbits;
134 if (nbits && (i >
int(ndigits))) {
135 xi |= x[i - ndigits - 1] >> (32 - nbits);
143 BigUInt<n>& BigUInt<n>::operator>>=(std::uint32_t b) {
144 auto ndigits = b / 32;
145 auto nbits = b - (ndigits * 32);
146 for (
int i = 0; i < n; ++i) {
147 std::uint32_t xi = 0;
148 if (i + ndigits < n) xi = x[i + ndigits] >> nbits;
149 if (nbits && i + ndigits + 1 < n) xi |= x[i + ndigits + 1] << (32 - nbits);
156 std::ostream& operator<<(std::ostream& os, BigUInt<n> a) {
161 divmod(quotient, a, 10);
162 auto remainder = a[0];
164 buf[i++] = char(remainder) +
'0';
166 for (
int j = 0; j < i / 2; ++j) {
167 auto tmp = buf[i - j - 1];
168 buf[i - j - 1] = buf[j];
171 if (i == 0) buf[i++] =
'0';
178 BigUInt<n> operator+(BigUInt<n>
const& a, BigUInt<n>
const& b) {
185 BigUInt<n> operator-(BigUInt<n>
const& a, BigUInt<n>
const& b) {
192 BigUInt<n> operator*(BigUInt<n>
const& a, BigUInt<n>
const& b) {
193 BigUInt<n> a_times_b_i;
195 for (
int i = n - 1; i >= 0; --i) {
205 BigUInt<n> operator/(BigUInt<n>
const& a, std::uint32_t
const& b) {
208 divmod(quotient, x, b);
213 BigUInt<n> operator/(BigUInt<n>
const& a, BigUInt<n>
const& b) {
214 if (b > a)
return BigUInt<n>(0);
215 BigUInt<n> quotient(1);
221 auto factor = quotient;
243 int comp(BigUInt<n>
const& a, BigUInt<n>
const& b) {
244 for (
int i = n - 1; i >= 0; --i) {
246 if (a[i] > b[i])
return 1;
254 bool operator>=(BigUInt<n>
const& a, BigUInt<n>
const& b) {
255 return comp(a, b) > -1;
259 bool operator<=(BigUInt<n>
const& a, BigUInt<n>
const& b) {
260 return comp(a, b) < 1;
264 bool operator<(BigUInt<n>
const& a, BigUInt<n>
const& b) {
265 return comp(a, b) == -1;
269 bool operator>(BigUInt<n>
const& a, BigUInt<n>
const& b) {
270 return comp(a, b) == 1;
274 bool operator==(BigUInt<n>
const& a, BigUInt<n>
const& b) {
275 for (
int i = 0; i < n; ++i)
if (a[i] != b[i])
return false;
280 void divmod(BigUInt<n>& quotient, BigUInt<n>& x, std::uint32_t
const& b) {
281 quotient = BigUInt<n>(std::uint32_t(0));
282 for (
int i = n - 1; i >= 0;) {
285 auto dividend = x[i];
286 auto quotient2 = dividend / b;
287 auto remainder = dividend - (quotient2 * b);
288 quotient[i] = quotient2;
291 auto dividend = std::uint64_t(x[i]);
293 dividend |= x[i - 1];
294 auto quotient2 = dividend / std::uint64_t(b);
295 auto remainder = dividend - (quotient2 * std::uint64_t(b));
296 quotient[i - 1] = std::uint32_t(quotient2);
298 x[i - 1] = std::uint32_t(remainder);
Arbitrary-precision unsigned integer declaration.