X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=blobdiff_plain;f=src%2Farbint.cpp;h=8af84f951f39694ad309e9ab96cb28a693ddd39b;hp=666b10eda0445ab2519f991fe16aad363517d7e2;hb=e88c1ef58e2446cf57d5f7b0d5d4e5bfff0b8c37;hpb=b02dcbab39b8c28b9baa41436842ca9fe4ae7ffd diff --git a/src/arbint.cpp b/src/arbint.cpp index 666b10e..8af84f9 100644 --- a/src/arbint.cpp +++ b/src/arbint.cpp @@ -81,7 +81,7 @@ unsigned Arbint::Shrink() unsigned shrunk = 0; while (m_digits.size() > 1 && m_digits[m_digits.size()-1] == 0L) { - Debug("Shrink 1"); + //Debug("Shrink 1"); m_digits.pop_back(); shrunk++; } @@ -91,12 +91,19 @@ unsigned Arbint::Shrink() void Arbint::GrowDigit(digit_t new_msd) { static unsigned total_grows = 0; + static unsigned biggest_arbint = 1; m_digits.push_back(new_msd); - Warn("Arbint grows digit (%.16lx), this->m_digits.size() = %u, total grown = %u", new_msd, m_digits.size(), ++total_grows); - if (total_grows++ > 10000) + total_grows++; + if (m_digits.size() > biggest_arbint) { - Fatal("Too many GrowDigit calls!"); + biggest_arbint = m_digits.size(); + Warn("New biggest Arbint of size %u", m_digits.size()); } + //Warn("Arbint grows digit (%.16lx), this->m_digits.size() = %u, total grown = %u", new_msd, m_digits.size(), ++total_grows); + //if (total_grows++ > 10000) + //{ + // Fatal("Too many GrowDigit calls!"); + //} } Arbint & Arbint::operator*=(const Arbint & mul) @@ -145,7 +152,7 @@ void Arbint::Division(const Arbint & div, Arbint & result, Arbint & remainder) c result.m_sign = !(m_sign == div.m_sign); return; } */ - + for (int i = 8*sizeof(digit_t)*m_digits.size(); i >= 0; --i) { remainder <<= 1; @@ -196,19 +203,28 @@ Arbint & Arbint::operator-=(const Arbint & sub) Arbint & Arbint::AddBasic(const Arbint & add) { + // Add any leading zeros to this number while (m_digits.size() < add.m_digits.size()) { - - Debug("Size is %u, add's size is %u", m_digits.size(), add.m_digits.size()); GrowDigit(0L); } //m_digits.resize(add.m_digits.size()+1,0L); digit_t carry = add_digits((digit_t*)m_digits.data(), (digit_t*)add.m_digits.data(), add.m_digits.size()); + + // This number had more digits but there is a carry left over + if (carry != 0L && m_digits.size() > add.m_digits.size()) + { + vector carry_digits(m_digits.size() - add.m_digits.size(), 0L); + carry_digits[0] = carry; + carry = add_digits((digit_t*)m_digits.data()+add.m_digits.size(), + (digit_t*)carry_digits.data(), m_digits.size()-add.m_digits.size()); + } + + // There is still a carry left over if (carry != 0L) { - Debug("Grow carry %lu", carry); GrowDigit(carry); } Shrink(); @@ -217,26 +233,26 @@ Arbint & Arbint::AddBasic(const Arbint & add) Arbint & Arbint::SubBasic(const Arbint & sub) { - bool fith = false; + // Add leading zeros while (sub.m_digits.size() > m_digits.size()) { - fith = true; GrowDigit(0L); } - if (fith) - { - Debug("START sub was %c%s, I am %c%s", SignChar(), sub.DigitStr().c_str(), SignChar(), DigitStr().c_str()); - } + // Do subtraction on digits digit_t borrow = sub_digits((digit_t*)m_digits.data(), (digit_t*)sub.m_digits.data(), sub.m_digits.size()); - - if (fith) + + // This number had more digits but there is a borrow left over + if (borrow != 0L && m_digits.size() > sub.m_digits.size()) { - Debug("SUB_DIGITS -> sub was %c%s, I am %c%s", SignChar(), sub.DigitStr().c_str(), SignChar(), DigitStr().c_str()); + vector borrow_digits(m_digits.size()-sub.m_digits.size(), 0L); + borrow_digits[0] = borrow; + borrow = sub_digits((digit_t*)m_digits.data()+sub.m_digits.size(), + (digit_t*)borrow_digits.data(), m_digits.size()-sub.m_digits.size()); } - - //TODO: Write ASM to do this bit? + + // borrow is still set => number is negative if (borrow != 0L) { m_sign = !m_sign; @@ -246,15 +262,7 @@ Arbint & Arbint::SubBasic(const Arbint & sub) one_digits[0] = 1L; add_digits((digit_t*)m_digits.data(), (digit_t*)one_digits.data(), m_digits.size()); } - if (fith) - { - Debug("END -> sub was %c%s, I am %c%s", sub.SignChar(), sub.DigitStr().c_str(), SignChar(), DigitStr().c_str()); - } Shrink(); - if (fith) - { - Debug("SHRUNK -> sub was %c%s, I am %c%s", sub.SignChar(), sub.DigitStr().c_str(), SignChar(), DigitStr().c_str()); - } return *this; } @@ -263,7 +271,16 @@ string Arbint::Str(const string & base) const { string s(""); Arbint cpy(*this); - + unsigned b = base.size(); + while (cpy > Arbint(0L)) + { + //Debug("cpy is %s", cpy.DigitStr().c_str()); + unsigned c = (unsigned)(cpy % Arbint(b)).AsDigit(); + s += base[c]; + cpy /= Arbint(b); + } + if (m_sign) + s += '-'; reverse(s.begin(), s.end()); return s; } @@ -361,7 +378,7 @@ Arbint & Arbint::operator<<=(unsigned amount) unsigned old_size = m_digits.size(); for (unsigned i = 0; i < whole; ++i) { - + //Debug("i = %u, whole = %u", i, whole); GrowDigit(0L);//m_digits.resize(m_digits.size() + whole); } memmove(m_digits.data()+whole, m_digits.data(), sizeof(digit_t)*old_size); @@ -420,7 +437,7 @@ void Arbint::BitSet(unsigned i) unsigned digit = i/(8*sizeof(digit_t)); while (m_digits.size() < digit+1) { - Debug("Grow BitSet Size %u, digit %u", m_digits.size(), digit); + //Debug("Grow BitSet Size %u, digit %u", m_digits.size(), digit); GrowDigit(0L); }