From: Sam Moore Date: Sat, 5 Jul 2014 09:33:39 +0000 (+0800) Subject: Division less buggy, still slow X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=commitdiff_plain;h=a7da45c62d5a0604785479f5dfeb1c2a65d0f9de Division less buggy, still slow Ok I need to put more thought into this. Or just look it up. --- diff --git a/src/arbint.cpp b/src/arbint.cpp index d61dabc..748330f 100644 --- a/src/arbint.cpp +++ b/src/arbint.cpp @@ -108,16 +108,32 @@ Arbint & Arbint::operator*=(const Arbint & mul) void Arbint::Division(const Arbint & div, Arbint & result, Arbint & remainder) const { - //TODO: Optimise? + if (div == Arbint(1L)) + { + result = *this; + remainder = 0L; + return; + } + if (div == *this) + { + result = 1L; + remainder = 0L; + return; + } + + + result = 0L; remainder = *this; - result = 0L; - while ((remainder -= div) > Arbint(0L)) + Arbint next_rem(remainder); + while ((next_rem -= div) >= Arbint(0L)) { - //Debug("Remainder %c%s", remainder.SignChar(), remainder.DigitStr().c_str()); - //Debug("Result %c%s + 1", result.SignChar(), result.DigitStr().c_str()); - result += 1; + //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; } - remainder += div; + + } Arbint & Arbint::operator+=(const Arbint & add) @@ -217,7 +233,8 @@ bool Arbint::IsZero() const bool Arbint::operator==(const Arbint & equ) const { - if (m_sign != equ.m_sign) return false; + if (m_sign != equ.m_sign) + return false; unsigned min_size = m_digits.size(); const Arbint * larger = &equ; if (m_digits.size() > equ.m_digits.size()) diff --git a/src/arbint.h b/src/arbint.h index 12f8302..4b819b9 100644 --- a/src/arbint.h +++ b/src/arbint.h @@ -101,7 +101,7 @@ namespace IPDF inline bool operator>=(const Arbint & leq) const { - return (this->operator==(leq) || this->operator<(leq)); + return (this->operator==(leq) || this->operator>(leq)); } inline bool operator>(const Arbint & grea) const { diff --git a/src/rational.h b/src/rational.h index ce1a767..6269ef1 100644 --- a/src/rational.h +++ b/src/rational.h @@ -16,9 +16,15 @@ namespace IPDF template T gcd(const T & a, const T & b) { - if (a == 1 || a == 0) return 1; - if (b == 0) return a; - if (b == a) return a; + Debug("Called on %li/%li", int64_t(a), int64_t(b)); + if (a == T(1) || a == T(0)) return T(1); + if (b == T(0)) return a; + if (b == a) + { + Debug("Equal!"); + return a; + } + Debug("Not equal!"); if (a > b) return gcd(a-b,b); return gcd(a, b-a); @@ -29,6 +35,8 @@ T gcd(const T & a, const T & b) template T gcd(const T & p, const T & q) { + + T g(1); T big(p); T small(q); @@ -41,11 +49,14 @@ T gcd(const T & p, const T & q) return g; while ((g = big % small) > T(0)) { + //Debug("big = %li, small = %li", int64_t(big), int64_t(small)); big = small; small = g; + //Debug("Loop %u", ++count); } return small; -} +} + template struct Rational @@ -80,6 +91,7 @@ struct Rational return; } T g = gcd(T(llabs(P)),T(llabs(Q))); + Debug("Got gcd!"); P /= g; Q /= g; } diff --git a/src/tests/arb.cpp b/src/tests/arb.cpp index b6e58cb..00bfefb 100644 --- a/src/tests/arb.cpp +++ b/src/tests/arb.cpp @@ -49,6 +49,7 @@ int main(int argc, char ** argv) assert((arb_a/arb_b).AsDigit() == a / b); assert((arb_a%arb_b).AsDigit() == a % b); } - printf("All tests successful!\n"); + printf("All single digit tests successful!\n"); + return 0; } diff --git a/src/tests/arbrationals.cpp b/src/tests/arbrationals.cpp new file mode 100644 index 0000000..3af559f --- /dev/null +++ b/src/tests/arbrationals.cpp @@ -0,0 +1,32 @@ +/** + * @file arbrationals.cpp + * @brief Tests Rational + */ + +#include "rational.h" +#include "arbint.h" + +#define TEST_CASES 100 + +using namespace std; +using namespace IPDF; + +int main(int argc, char ** argv) +{ + for (unsigned i = 0; i < TEST_CASES; ++i) + { + Debug("Cycle %u",i); + Arbint p1 = 1L;//rand(); + Arbint q1 = 2L;//rand(); + Arbint p2 = rand(); + Arbint q2 = rand(); + Debug("Construct rationals"); + Rational a(p1, q1); + Debug("Constructed a %u\n",i); + Rational b(p2, q2); + Debug("Constructed b %u\n",i); + + + } + printf("Tests done"); +}