From c508dc2a4abd364d6d067f85041050b1b0f5f9aa Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Thu, 20 Oct 2011 00:38:49 +0000 Subject: [PATCH] core: dynamically allocate mantissa for real numbers. One day we'll be able to modify their precision at runtime. --- src/real.cpp | 56 +++++++++++++++++++++++++++++++++++++++++----------- src/real.h | 20 ++++++++++--------- 2 files changed, 55 insertions(+), 21 deletions(-) diff --git a/src/real.cpp b/src/real.cpp index 4aef4154..066cb38e 100644 --- a/src/real.cpp +++ b/src/real.cpp @@ -22,12 +22,43 @@ using namespace std; namespace lol { -real::real(float f) { *this = (double)f; } -real::real(int i) { *this = (double)i; } -real::real(unsigned int i) { *this = (double)i; } +real::real() +{ + m_mantissa = new uint32_t[BIGITS]; + m_signexp = 0; +} + +real::real(real const &x) +{ + m_mantissa = new uint32_t[BIGITS]; + memcpy(m_mantissa, x.m_mantissa, BIGITS * sizeof(uint32_t)); + m_signexp = x.m_signexp; +} + +real const &real::operator =(real const &x) +{ + if (&x != this) + { + memcpy(m_mantissa, x.m_mantissa, BIGITS * sizeof(uint32_t)); + m_signexp = x.m_signexp; + } + + return *this; +} + +real::~real() +{ + delete[] m_mantissa; +} + +real::real(float f) { new(this) real((double)f); } +real::real(int i) { new(this) real((double)i); } +real::real(unsigned int i) { new(this) real((double)i); } real::real(double d) { + new(this) real(); + union { double d; uint64_t x; } u = { d }; uint32_t sign = (u.x >> 63) << 31; @@ -198,12 +229,13 @@ real real::operator -(real const &x) const int64_t carry = 0; for (int i = 0; i < bigoff; i++) { - carry -= x.m_mantissa[BIGITS - i]; + carry -= x.m_mantissa[BIGITS - 1 - i]; /* Emulates a signed shift */ carry >>= BIGIT_BITS; carry |= carry << BIGIT_BITS; } - carry -= x.m_mantissa[BIGITS - 1 - bigoff] & (((int64_t)1 << off) - 1); + if (bigoff < BIGITS) + carry -= x.m_mantissa[BIGITS - 1 - bigoff] & (((int64_t)1 << off) - 1); carry /= (int64_t)1 << off; for (int i = BIGITS; i--; ) @@ -344,25 +376,25 @@ real real::operator /(real const &x) const return *this * re(x); } -real &real::operator +=(real const &x) +real const &real::operator +=(real const &x) { real tmp = *this; return *this = tmp + x; } -real &real::operator -=(real const &x) +real const &real::operator -=(real const &x) { real tmp = *this; return *this = tmp - x; } -real &real::operator *=(real const &x) +real const &real::operator *=(real const &x) { real tmp = *this; return *this = tmp * x; } -real &real::operator /=(real const &x) +real const &real::operator /=(real const &x) { real tmp = *this; return *this = tmp / x; @@ -380,14 +412,14 @@ real real::operator >>(int x) const return tmp >>= x; } -real &real::operator <<=(int x) +real const &real::operator <<=(int x) { if (m_signexp << 1) m_signexp += x; return *this; } -real &real::operator >>=(int x) +real const &real::operator >>=(int x) { if (m_signexp << 1) m_signexp -= x; @@ -402,7 +434,7 @@ bool real::operator ==(real const &x) const if (m_signexp != x.m_signexp) return false; - return memcmp(m_mantissa, x.m_mantissa, sizeof(m_mantissa)) == 0; + return memcmp(m_mantissa, x.m_mantissa, BIGITS * sizeof(uint32_t)) == 0; } bool real::operator !=(real const &x) const diff --git a/src/real.h b/src/real.h index a6de7e93..57f59434 100644 --- a/src/real.h +++ b/src/real.h @@ -24,7 +24,10 @@ namespace lol class real { public: - inline real() { } + real(); + real(real const &x); + real const &operator =(real const &x); + ~real(); real(float f); real(double f); @@ -42,15 +45,15 @@ public: real operator -(real const &x) const; real operator *(real const &x) const; real operator /(real const &x) const; - real &operator +=(real const &x); - real &operator -=(real const &x); - real &operator *=(real const &x); - real &operator /=(real const &x); + real const &operator +=(real const &x); + real const &operator -=(real const &x); + real const &operator *=(real const &x); + real const &operator /=(real const &x); real operator <<(int x) const; real operator >>(int x) const; - real &operator <<=(int x); - real &operator >>=(int x); + real const &operator <<=(int x); + real const &operator >>=(int x); bool operator ==(real const &x) const; bool operator !=(real const &x) const; @@ -133,9 +136,8 @@ public: static int const BIGIT_BITS = 32; private: - uint32_t m_size; + uint32_t *m_mantissa; uint32_t m_signexp; - uint32_t m_mantissa[BIGITS]; }; } /* namespace lol */