Division less buggy, still slow
authorSam Moore <matches@ucc.asn.au>
Sat, 5 Jul 2014 09:33:39 +0000 (17:33 +0800)
committerSam Moore <matches@ucc.asn.au>
Sat, 5 Jul 2014 09:33:39 +0000 (17:33 +0800)
Ok I need to put more thought into this. Or just look it up.

src/arbint.cpp
src/arbint.h
src/rational.h
src/tests/arb.cpp
src/tests/arbrationals.cpp [new file with mode: 0644]

index d61dabc..748330f 100644 (file)
@@ -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())
index 12f8302..4b819b9 100644 (file)
@@ -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
                        {
index ce1a767..6269ef1 100644 (file)
@@ -16,9 +16,15 @@ namespace IPDF
 template <class T>
 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 <class T>
 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 <class T = int64_t>
 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;
        }
index b6e58cb..00bfefb 100644 (file)
@@ -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 (file)
index 0000000..3af559f
--- /dev/null
@@ -0,0 +1,32 @@
+/**
+ * @file arbrationals.cpp
+ * @brief Tests Rational<Arbint>
+ */
+#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<Arbint> a(p1, q1);
+               Debug("Constructed a %u\n",i);
+               Rational<Arbint> b(p2, q2);
+               Debug("Constructed b %u\n",i);
+               
+               
+       }
+       printf("Tests done");
+}

UCC git Repository :: git.ucc.asn.au