+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.size()), m_sign(cpy.m_sign)
+{
+ memcpy(m_digits.data(), cpy.m_digits.data(),
+ sizeof(digit_t)*m_digits.size());
+}
+
+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 & add)
+{
+ if (m_sign == add.m_sign)
+ {
+ // -a + -b == -(a + b)
+ return AddBasic(add);
+ }
+
+ if (m_sign)
+ {
+ // -a + b == -(a - b)
+ m_sign = false;
+ SubBasic(add);
+ m_sign = !m_sign;
+ }
+ else
+ {
+ // a + -b == a - b
+ SubBasic(add);
+ }
+ return *this;
+}
+
+Arbint & Arbint::operator-=(const Arbint & sub)