Merge branch 'master' of git.ucc.asn.au:ipdf/code
authorDavid Gow <[email protected]>
Mon, 7 Jul 2014 16:02:11 +0000 (00:02 +0800)
committerDavid Gow <[email protected]>
Mon, 7 Jul 2014 16:02:11 +0000 (00:02 +0800)
src/Makefile
src/arbint.cpp
src/gmpint.h [new file with mode: 0644]
src/rational.h
src/real.cpp
src/real.h
src/tests/arbint_vs_gmpint.cpp [new file with mode: 0644]
src/tests/asm.cpp [deleted file]
src/tests/realops.cpp

index ec8789a..64408ed 100644 (file)
@@ -4,8 +4,8 @@ ARCH := $(shell uname -m)
 CXX = g++ -std=gnu++0x -g -Wall -Werror -Wshadow -pedantic -rdynamic
 MAIN = main.o
 OBJ = log.o real.o bezier.o document.o objectrenderer.o view.o screen.o vfpu.o graphicsbuffer.o framebuffer.o shaderprogram.o stb_truetype.o gl_core44.o add_digits_asm.o sub_digits_asm.o mul_digits_asm.o div_digits_asm.o arbint.o
-LIB_x86_64 = ../contrib/lib/libSDL2-2.0.so.0 -lGL
-LIB_i386 = ../contrib/lib32/libSDL2-2.0.so.0 -lGL
+LIB_x86_64 = ../contrib/lib/libSDL2-2.0.so.0 -lGL -lgmp
+LIB_i386 = ../contrib/lib32/libSDL2-2.0.so.0 -lGL -lgmp
 
 MAINRPATH_x86_64 = -Wl,-rpath,'$$ORIGIN/../contrib/lib'
 MAINRPATH_i386 = -Wl,-rpath,'$$ORIGIN/../contrib/lib32'
index df6da8d..8af84f9 100644 (file)
@@ -271,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;
 }
diff --git a/src/gmpint.h b/src/gmpint.h
new file mode 100644 (file)
index 0000000..4f45231
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ * @file gmpint.h
+ * @brief Wraps to GMP mpz_t type using inlines
+ */
+
+#ifndef _GMPINT_H
+#define _GMPINT_H
+
+#include <gmp.h>
+#include <string>
+
+class Gmpint
+{
+       public:
+               Gmpint(int64_t i) {mpz_init_set_si(m_op, i);}
+               Gmpint(const std::string & str, int base=10) {mpz_init_set_str(m_op, str.c_str(), base);}
+               Gmpint(const Gmpint & cpy) {mpz_init(m_op); mpz_set(m_op, cpy.m_op);}
+               virtual ~Gmpint() {} //TODO: Do we need to delete m_op somehow?
+               
+               
+               operator int64_t() const {return mpz_get_si(m_op);}
+               operator uint64_t() const {return mpz_get_ui(m_op);}
+               operator double() const {return mpz_get_d(m_op);}
+               std::string Str(int base = 10) const
+               {
+                       //TODO: Make less hacky, if we care.
+                       char * buff = mpz_get_str(NULL, 10, m_op);
+                       std::string result(buff);
+                       free(buff);
+                       return result;
+               }
+               
+               Gmpint & operator=(const Gmpint & equ) {mpz_set(m_op, equ.m_op); return *this;}
+               Gmpint & operator+=(const Gmpint & add) {mpz_add(m_op, m_op, add.m_op); return *this;}
+               Gmpint & operator-=(const Gmpint & sub) {mpz_sub(m_op, m_op, sub.m_op); return *this;}
+               Gmpint & operator*=(const Gmpint & mul) {mpz_mul(m_op, m_op, mul.m_op); return *this;}
+               Gmpint & operator/=(const Gmpint & div) {mpz_div(m_op, m_op, div.m_op); return *this;}
+               
+               Gmpint operator+(const Gmpint & add) const {Gmpint a(*this); a += add; return a;}
+               Gmpint operator-(const Gmpint & sub) const {Gmpint a(*this); a -= sub; return a;}
+               Gmpint operator*(const Gmpint & mul) const {Gmpint a(*this); a *= mul; return a;}
+               Gmpint operator/(const Gmpint & div) const {Gmpint a(*this); a /= div; return a;}
+               Gmpint operator%(const Gmpint & div) const {Gmpint a(*this); mpz_mod(a.m_op, a.m_op, div.m_op); return a;}
+               Gmpint operator-() const {return (Gmpint(0L)-*this);}
+               
+               
+               bool operator==(const Gmpint & cmp) const {return mpz_cmp(m_op, cmp.m_op) == 0;}
+               bool operator!=(const Gmpint & cmp) const {return mpz_cmp(m_op, cmp.m_op) != 0;}
+               bool operator<(const Gmpint & cmp) const {return mpz_cmp(m_op, cmp.m_op) < 0;}
+               bool operator>(const Gmpint & cmp) const {return mpz_cmp(m_op, cmp.m_op) > 0;}
+               bool operator<=(const Gmpint & cmp) const {return mpz_cmp(m_op, cmp.m_op) <= 0;}
+               bool operator>=(const Gmpint & cmp) const {return mpz_cmp(m_op, cmp.m_op) >= 0;}
+               
+               Gmpint Abs() const {Gmpint a(*this); mpz_abs(a.m_op, a.m_op); return a;}
+               
+               
+       private:
+               Gmpint(const mpz_t & op) : m_op(op) {}
+               mpz_t m_op;
+};     
+
+
+
+
+#endif //_GMPINT_H
index 61a38ab..6bc5aec 100644 (file)
@@ -9,6 +9,7 @@
 #include <cmath>
 #include <cassert>
 #include "arbint.h"
+#include "gmpint.h"
 
 namespace IPDF
 {
@@ -18,7 +19,7 @@ template <class T> T Tabs(const T & a)
        return abs(a);
 }
 template <> Arbint Tabs(const Arbint & a);
-
+template <> Gmpint Tabs(const Gmpint & a);
 
 /* Recursive version  of GCD
 template <class T>
index 83b3fb8..ce2f976 100644 (file)
@@ -11,5 +11,10 @@ namespace IPDF
                "Rational<int64_t>", 
                "Rational<Arbint>"
        };
+       
+       template <> Gmpint Tabs(const Gmpint & a)
+       {
+               return a.Abs();
+       }
 
 }
index 8dea953..798ea0b 100644 (file)
@@ -26,6 +26,7 @@
 #if REAL == REAL_RATIONAL_ARBINT
        #include "rational.h"
        #include "arbint.h"
+       #include "gmpint.h"
 #endif //REAL
 
 namespace IPDF
@@ -48,14 +49,16 @@ namespace IPDF
        inline float Float(const Real & r) {return (float)r.ToDouble();}
        inline double Double(const Real & r) {return r.ToDouble();}
 #elif REAL == REAL_RATIONAL_ARBINT
-       typedef Rational<Arbint> Real;
+       #define ARBINT Gmpint // Set to Gmpint or Arbint here
+       
+       typedef Rational<ARBINT> Real;
        inline float Float(const Real & r) {return (float)r.ToDouble();}
        inline double Double(const Real & r) {return r.ToDouble();}
-       inline Rational<Arbint> pow(const Rational<Arbint> & a, const Rational<Arbint> & b)
+       inline Rational<ARBINT> pow(const Rational<ARBINT> & a, const Rational<ARBINT> & b)
        {
-               Arbint P(std::pow(static_cast<double>(a.P), b.ToDouble()));
-               Arbint Q(std::pow(static_cast<double>(a.Q), b.ToDouble()));
-               return Rational<Arbint>(P,Q);
+               ARBINT P(std::pow(static_cast<double>(a.P), b.ToDouble()));
+               ARBINT Q(std::pow(static_cast<double>(a.Q), b.ToDouble()));
+               return Rational<ARBINT>(P,Q);
        }
 #else
        #error "Type of Real unspecified."
diff --git a/src/tests/arbint_vs_gmpint.cpp b/src/tests/arbint_vs_gmpint.cpp
new file mode 100644 (file)
index 0000000..306bbb7
--- /dev/null
@@ -0,0 +1,40 @@
+#include <gmp.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "log.h"
+
+#include "gmpint.h"
+#include "arbint.h"
+
+#define TEST_CASES 100
+
+using namespace IPDF;
+
+int main(int argc, char ** argv)
+{
+       for (unsigned i = 0; i < TEST_CASES; ++i)
+       {
+               uint64_t a = rand();
+       
+               Arbint arb_a(a);
+               Gmpint gmp_a(a);
+               
+               uint64_t b = rand();
+               
+               for (unsigned j = 0; j < 5; ++j)
+               {
+                       arb_a *= b;
+                       gmp_a *= b;
+               }
+               
+               for (unsigned j = 0; j < 5; ++j)
+               {
+                       arb_a /= b;
+                       gmp_a /= b;
+               }
+               
+               
+       }
+       return 0;
+}
diff --git a/src/tests/asm.cpp b/src/tests/asm.cpp
deleted file mode 100644 (file)
index aa17b3b..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <cstdlib>
-#include <cstdio>
-#include <iostream>
-
-using namespace std;
-
-
-
-int main(int argc, char ** argv)
-{
-       uint32_t a = 4294967295;
-       uint32_t b = 0;
-       uint32_t r = 0;
-       bool c = addc(a, b, &r);
-       printf("%u + %u = %u (%u)\n", a, b, r, (uint32_t)c);
-       
-}
index 83a5241..b9ce441 100644 (file)
@@ -10,7 +10,7 @@ static double g_totalerror = 0;
 
 bool NotEqual(double a, double b, double threshold=1e-1)
 {
-       double error = (fabs(a-b) > threshold);
+       double error = fabs(a-b);
        g_totalerror += error;
        return (error > threshold);
 }

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