Browse Source

core: add operators +=, *= etc. to the real class, and refactor the

print() method so that it displays decimal values.
legacy
Sam Hocevar sam 13 years ago
parent
commit
58ee1d5b81
2 changed files with 104 additions and 14 deletions
  1. +93
    -14
      src/real.cpp
  2. +11
    -0
      src/real.h

+ 93
- 14
src/real.cpp View File

@@ -22,10 +22,9 @@ using namespace std;
namespace lol
{

real::real(float f)
{
new(this) real((double)f);
}
real::real(float f) { *this = (double)f; }
real::real(int i) { *this = (double)i; }
real::real(unsigned int i) { *this = (double)i; }

real::real(double d)
{
@@ -54,10 +53,9 @@ real::real(double d)
memset(m_mantissa + 4, 0, sizeof(m_mantissa) - 4 * sizeof(m_mantissa[0]));
}

real::operator float() const
{
return (float)(double)(*this);
}
real::operator float() const { return (float)(double)(*this); }
real::operator int() const { return (int)(double)(*this); }
real::operator unsigned int() const { return (unsigned int)(double)(*this); }

real::operator double() const
{
@@ -315,6 +313,43 @@ real real::operator /(real const &x) const
return *this * fres(x);
}

real &real::operator +=(real const &x)
{
real tmp = *this;
return *this = tmp + x;
}

real &real::operator -=(real const &x)
{
real tmp = *this;
return *this = tmp - x;
}

real &real::operator *=(real const &x)
{
real tmp = *this;
return *this = tmp * x;
}

real &real::operator /=(real const &x)
{
real tmp = *this;
return *this = tmp / x;
}

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;
}

bool real::operator !=(real const &x) const
{
return !(*this == x);
}

bool real::operator <(real const &x) const
{
/* Ensure both numbers are positive */
@@ -384,8 +419,6 @@ real fres(real const &x)
real ret;
ret.m_mantissa[0] = (v.x >> 7) & 0xffffu;
ret.m_mantissa[1] = (v.x << 9) & 0xffffu;
/* Better convergence with the mantissa zeroed. */
memset(ret.m_mantissa + 2, 0, (real::BIGITS - 2) * sizeof(uint16_t));

uint32_t sign = x.m_signexp & 0x80000000u;
ret.m_signexp = sign;
@@ -395,7 +428,7 @@ real fres(real const &x)
ret.m_signexp |= (exponent - 1) & 0x7fffffffu;

/* Five steps of Newton-Raphson seems enough for 32-bigit reals. */
real two(2.0f);
real two = 2;
ret = ret * (two - ret * x);
ret = ret * (two - ret * x);
ret = ret * (two - ret * x);
@@ -407,9 +440,55 @@ real fres(real const &x)

void real::print() const
{
printf("%x %08x ", m_signexp >> 31, (m_signexp << 1) >> 1);
for (int i = 0; i < BIGITS; i++)
printf("%04x ", m_mantissa[i]);
real const r1 = 1, r10 = 10;
real x = *this;

if (x.m_signexp >> 31)
{
printf("-");
x = -x;
}

/* Normalise x so that mantissa is in [1..9.999] */
int exponent = 0;
for (real div = r1, newdiv; true; div = newdiv)
{
newdiv = div * r10;
if (x < newdiv)
{
x /= div;
break;
}
exponent++;
}
for (real mul = 1, newx; true; mul *= r10)
{
newx = x * mul;
if (newx >= r1)
{
x = newx;
break;
}
exponent--;
}

/* Print digits */
for (int i = 0; i < 150; i++)
{
int digit = (int)x;
printf("%i", digit);
if (i == 0)
printf(".");
x -= real(digit);
x *= r10;
}

/* Print exponent information */
if (exponent < 0)
printf("e-%i", -exponent);
else if (exponent > 0)
printf("e+%i", exponent);

printf("\n");
}



+ 11
- 0
src/real.h View File

@@ -27,18 +27,29 @@ class real

public:
inline real() { }

real(float f);
real(double f);
real(int i);
real(unsigned int i);

operator float() const;
operator double() const;
operator int() const;
operator unsigned int() const;

real operator -() const;
real operator +(real const &x) const;
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);

bool operator ==(real const &x) const;
bool operator !=(real const &x) const;
bool operator <(real const &x) const;
bool operator >(real const &x) const;
bool operator <=(real const &x) const;


Loading…
Cancel
Save