+Arbint::Arbint(unsigned n, digit_t d0, ...) : m_digits(n), m_sign(false)
+{
+ va_list ap;
+ va_start(ap, d0);
+ if (n > 1)
+ m_digits[0] = d0;
+ for (unsigned i = 1; i < n; ++i)
+ {
+ m_digits[i] = va_arg(ap, digit_t);
+ }
+ va_end(ap);
+}
+
+Arbint::Arbint(const Arbint & cpy) : m_digits(cpy.m_digits), m_sign(cpy.m_sign)
+{
+
+}
+
+Arbint::Arbint(const vector<digit_t> & digits) : m_digits(digits), m_sign(false)
+{
+
+}
+
+Arbint & Arbint::operator=(const Arbint & cpy)
+{
+ memmove(m_digits.data(), cpy.m_digits.data(),
+ sizeof(digit_t)*min(m_digits.size(), cpy.m_digits.size()));
+ if (cpy.m_digits.size() > m_digits.size())
+ {
+ unsigned old_size = m_digits.size();
+ m_digits.resize(cpy.m_digits.size());
+ memset(m_digits.data()+old_size, 0, sizeof(digit_t)*m_digits.size()-old_size);
+ }
+ return *this;
+}
+
+void Arbint::Zero()
+{
+ memset(m_digits.data(), 0, sizeof(digit_t)*m_digits.size());
+}
+
+unsigned Arbint::Shrink()
+{
+ if (m_digits.size() <= 1)
+ return 0;
+ unsigned i;
+ for (i = m_digits.size()-1; (i > 0 && m_digits[i] != 0L); --i);
+ unsigned result = m_digits.size() - i;
+ m_digits.resize(i);
+ return result;
+}
+
+Arbint & Arbint::operator*=(const Arbint & mul)
+{
+ vector<digit_t> new_digits(m_digits.size(), 0L);
+ new_digits.reserve(new_digits.size()+mul.m_digits.size());
+ for (unsigned i = 0; i < mul.m_digits.size(); ++i)
+ {
+ vector<digit_t> step(m_digits.size()+i, 0L);
+ memcpy(step.data()+i, m_digits.data(), sizeof(digit_t)*m_digits.size());
+
+ digit_t overflow = mul_digits((digit_t*)step.data()+i, mul.m_digits[i], m_digits.size());
+ if (overflow != 0L)
+ {
+ step.push_back(overflow);
+ }
+ new_digits.resize(max(new_digits.size(), step.size()), 0L);
+ digit_t carry = add_digits((digit_t*)new_digits.data(), step.data(), step.size());
+ if (carry != 0L)
+ {
+ new_digits.push_back(carry);
+ }
+ }
+
+ m_digits.swap(new_digits);
+ m_sign = !(m_sign == mul.m_sign);
+ return *this;
+}
+
+void Arbint::Division(const Arbint & div, Arbint & result, Arbint & remainder) const
+{
+ if (div == Arbint(1L))
+ {
+ result = *this;
+ remainder = 0L;
+ return;
+ }
+ if (div == *this)
+ {
+ result = 1L;
+ remainder = 0L;
+ return;
+ }
+
+
+ result = 0L;
+ remainder = *this;
+ Arbint next_rem(remainder);
+ while ((next_rem -= div) >= Arbint(0L))
+ {
+ //Debug("%li - %li = %li", digit_t(remainder), digit_t(div), digit_t(next_rem));
+ //Debug("Sign is %d", next_rem.m_sign);
+ remainder = next_rem;
+ result += 1L;
+ }
+
+
+}
+
+Arbint & Arbint::operator+=(const Arbint & add)