From: Sam Moore Date: Fri, 3 Oct 2014 06:25:06 +0000 (+0800) Subject: Keeping it Real, add Gmprat::Str, Gmprat::Log10 X-Git-Url: https://git.ucc.asn.au/?p=ipdf%2Fcode.git;a=commitdiff_plain;h=6b7e92069596a3f19fbe068b14a9c5ef59c22061 Keeping it Real, add Gmprat::Str, Gmprat::Log10 Fixed* all those horrible compile errors. View can now use VReal and Path can now use PReal and at the moment they are Gmprat unless the quadtree is enabled. For Gmprat::Log10 there are problems. Using: log(a/b) = log(a) - log(b) log(a*b) = log(a) + log(b) Unfortunately mpz_div_ui quickly becomes a massive performance issue. Even when well within the range of IEEE singles. Need to rewrite Gmprat::Log10 but may as well commit since it works* slowly at least. --- diff --git a/src/gmprat.h b/src/gmprat.h index e0472ca..6782734 100644 --- a/src/gmprat.h +++ b/src/gmprat.h @@ -20,18 +20,67 @@ class Gmprat //operator int64_t() const {return mpq_get_si(m_op);} //operator uint64_t() const {return mpq_get_ui(m_op);} - //operator double() const {return mpq_get_d(m_op);} + operator double() const {return mpq_get_d(m_op);} //operator float() const {return (float)ToDouble();} double ToDouble() const {return mpq_get_d(m_op);} - std::string Str(int base = 10) const + std::string Str() const { //TODO: Make less hacky, if we care. - char * buff = mpq_get_str(NULL, 10, m_op); - std::string result(buff); - free(buff); - return result; + // Convert to scientific notation + if (Negative()) + { + return "-" + operator-().Str(); + } + double p = Log10(); + if (isinf(p)) + return "0"; + + int P = (int)p; + double C = pow(10.0, p - P); + std::stringstream s; + s << C; + if (P != 0) + s << "e"<< P; + //s << "("< 10) + { + + mpz_div_ui(num, num, 1e10); + lognum += 10; + } + uint64_t n = mpz_get_ui(num); + if (n == 0) + { + return -INFINITY; + } + lognum += log(n)/log(10.0); + //Debug("%lu", mpz_get_ui(den)); + while (mpz_sizeinbase(den, 10) > 10) + { + mpz_div_ui(den, den, 1e10); + logden += 10; + } + uint64_t d = mpz_get_ui(den); + // if d is zero, its been rounded down we hope + if (d != 0) + logden += log(d)/log(10.0); + + return (lognum - logden); + } + + + bool Negative() const {return (mpz_sgn(mpq_numref(m_op)) < 0);} + Gmprat & operator=(const Gmprat & equ) {mpq_set(m_op, equ.m_op); return *this;} Gmprat & operator=(const double & equ) {mpq_set_d(m_op, equ); return *this;} Gmprat & operator+=(const Gmprat & add) {mpq_add(m_op, m_op, add.m_op); return *this;} @@ -62,7 +111,7 @@ class Gmprat mpq_t m_op; }; -std::ostream & operator<<(std::ostream & os, const Gmprat & fith) +inline std::ostream & operator<<(std::ostream & os, const Gmprat & fith) { os << fith.Str(); return os; diff --git a/src/graphicsbuffer.cpp b/src/graphicsbuffer.cpp index 8075453..844dfe8 100644 --- a/src/graphicsbuffer.cpp +++ b/src/graphicsbuffer.cpp @@ -243,7 +243,7 @@ void GraphicsBuffer::UploadRange(size_t length, intptr_t offset, const void* dat void GraphicsBuffer::Resize(size_t length) { - if (m_invalidated && m_buffer_size > length) + if (m_invalidated && m_buffer_size >= length) { m_buffer_size = length; } diff --git a/src/real.h b/src/real.h index 72def69..35b2c5e 100644 --- a/src/real.h +++ b/src/real.h @@ -22,7 +22,7 @@ #define XSTR(x) STR(x) #define STR(x) #x -#pragma message "REALTYPE = " XSTR(REALTYPE) +//#pragma message "REALTYPE = " XSTR(REALTYPE) #if REALTYPE == REAL_VFPU #include "vfpu.h" diff --git a/src/rect.h b/src/rect.h index 25ef94e..0188446 100644 --- a/src/rect.h +++ b/src/rect.h @@ -12,6 +12,7 @@ namespace IPDF T x; T y; T w; T h; //TRect() = default; // Needed so we can fread/fwrite this struct TRect(T _x=0, T _y=0, T _w=1, T _h=1) : x(_x), y(_y), w(_w), h(_h) {} + template TRect(const TRect & cpy) : x(T(cpy.x)), y(T(cpy.y)), w(T(cpy.w)), h(T(cpy.h)) {} std::string Str() const { @@ -38,7 +39,16 @@ namespace IPDF return true; } - template TRect Convert() {return TRect(B(x), B(y), B(w), B(h));} + template TRect Convert() const {return TRect(B(x), B(y), B(w), B(h));} + + template TRect & operator=(const TRect & equ) + { + x = T(equ.x); + y = T(equ.y); + w = T(equ.w); + h = T(equ.h); + return *this; + } }; diff --git a/src/view.cpp b/src/view.cpp index 0807643..53511d2 100644 --- a/src/view.cpp +++ b/src/view.cpp @@ -84,7 +84,7 @@ View::~View() * Translate the view * @param x, y - Amount to translate */ -void View::Translate(VReal x, VReal y) +void View::Translate(Real x, Real y) { if (!m_use_gpu_transform) m_buffer_dirty = true; @@ -94,12 +94,10 @@ void View::Translate(VReal x, VReal y) #ifdef TRANSFORM_BEZIERS_TO_PATH type = PATH; #endif - m_document.TranslateObjects(-x.ToDouble(), -y.ToDouble(), type); + m_document.TranslateObjects(-x, -y, type); #endif - x *= m_bounds.w; - y *= m_bounds.h; - m_bounds.x += x; - m_bounds.y += y; + m_bounds.x += m_bounds.w*VReal(x); + m_bounds.y += m_bounds.h*VReal(y); //Debug("View Bounds => %s", m_bounds.Str().c_str()); @@ -125,7 +123,7 @@ void View::SetBounds(const Rect & bounds) * @param x, y - Coordinates to scale at (eg: Mouse cursor position) * @param scale_amount - Amount to scale by */ -void View::ScaleAroundPoint(VReal x, VReal y, VReal scale_amount) +void View::ScaleAroundPoint(Real x, Real y, Real scale_amount) { // (x0, y0, w, h) -> (x*w - (x*w - x0)*s, y*h - (y*h - y0)*s, w*s, h*s) @@ -143,19 +141,19 @@ void View::ScaleAroundPoint(VReal x, VReal y, VReal scale_amount) #endif m_document.ScaleObjectsAboutPoint(x, y, scale_amount, type); #endif - x *= m_bounds.w; - y *= m_bounds.h; - x += m_bounds.x; - y += m_bounds.y; + VReal vx = m_bounds.w * VReal(x); + VReal vy = m_bounds.h * VReal(y); + vx += m_bounds.x; + vy += m_bounds.y; - VReal top = y - m_bounds.y; - VReal left = x - m_bounds.x; + VReal top = vy - m_bounds.y; + VReal left = vx - m_bounds.x; top *= scale_amount; left *= scale_amount; - m_bounds.x = x - left; - m_bounds.y = y - top; + m_bounds.x = vx - left; + m_bounds.y = vy - top; m_bounds.w *= scale_amount; m_bounds.h *= scale_amount; //Debug("Scale at {%s, %s} by %s View Bounds => %s", x.Str().c_str(), y.Str().c_str(), scale_amount.Str().c_str(), m_bounds.Str().c_str()); @@ -174,7 +172,7 @@ Rect View::TransformToViewCoords(const Rect& inp) const #ifdef TRANSFORM_OBJECTS_NOT_VIEW return inp; #endif - return TransformRectCoordinates(m_bounds, inp); + return TransformRectCoordinates(m_bounds.Convert(), inp); } /** diff --git a/src/view.h b/src/view.h index 47eb0fb..1cb2221 100644 --- a/src/view.h +++ b/src/view.h @@ -39,8 +39,8 @@ namespace IPDF void Render(int width = 0, int height = 0); - void Translate(VReal x, VReal y); - void ScaleAroundPoint(VReal x, VReal y, VReal scale_amount); + void Translate(Real x, Real y); + void ScaleAroundPoint(Real x, Real y, Real scale_amount); void SetBounds(const Rect & new_bounds); Rect TransformToViewCoords(const Rect& inp) const;