Changeset 983


Ignore:
Timestamp:
Sep 27, 2011, 1:20:47 AM (11 years ago)
Author:
sam
Message:

core: add operators +=, *= etc. to the real class, and refactor the
print() method so that it displays decimal values.

Location:
trunk/src
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/real.cpp

    r982 r983  
    2323{
    2424
    25 real::real(float f)
    26 {
    27     new(this) real((double)f);
    28 }
     25real::real(float f) { *this = (double)f; }
     26real::real(int i) { *this = (double)i; }
     27real::real(unsigned int i) { *this = (double)i; }
    2928
    3029real::real(double d)
     
    5554}
    5655
    57 real::operator float() const
    58 {
    59     return (float)(double)(*this);
    60 }
     56real::operator float() const { return (float)(double)(*this); }
     57real::operator int() const { return (int)(double)(*this); }
     58real::operator unsigned int() const { return (unsigned int)(double)(*this); }
    6159
    6260real::operator double() const
     
    316314}
    317315
     316real &real::operator +=(real const &x)
     317{
     318    real tmp = *this;
     319    return *this = tmp + x;
     320}
     321
     322real &real::operator -=(real const &x)
     323{
     324    real tmp = *this;
     325    return *this = tmp - x;
     326}
     327
     328real &real::operator *=(real const &x)
     329{
     330    real tmp = *this;
     331    return *this = tmp * x;
     332}
     333
     334real &real::operator /=(real const &x)
     335{
     336    real tmp = *this;
     337    return *this = tmp / x;
     338}
     339
     340bool real::operator ==(real const &x) const
     341{
     342    if (m_signexp != x.m_signexp)
     343        return false;
     344
     345    return memcmp(m_mantissa, x.m_mantissa, sizeof(m_mantissa)) == 0;
     346}
     347
     348bool real::operator !=(real const &x) const
     349{
     350    return !(*this == x);
     351}
     352
    318353bool real::operator <(real const &x) const
    319354{
     
    385420    ret.m_mantissa[0] = (v.x >> 7) & 0xffffu;
    386421    ret.m_mantissa[1] = (v.x << 9) & 0xffffu;
    387     /* Better convergence with the mantissa zeroed. */
    388     memset(ret.m_mantissa + 2, 0, (real::BIGITS - 2) * sizeof(uint16_t));
    389422
    390423    uint32_t sign = x.m_signexp & 0x80000000u;
     
    396429
    397430    /* Five steps of Newton-Raphson seems enough for 32-bigit reals. */
    398     real two(2.0f);
     431    real two = 2;
    399432    ret = ret * (two - ret * x);
    400433    ret = ret * (two - ret * x);
     
    408441void real::print() const
    409442{
    410     printf("%x  %08x  ", m_signexp >> 31, (m_signexp << 1) >> 1);
    411     for (int i = 0; i < BIGITS; i++)
    412         printf("%04x ", m_mantissa[i]);
     443    real const r1 = 1, r10 = 10;
     444    real x = *this;
     445
     446    if (x.m_signexp >> 31)
     447    {
     448        printf("-");
     449        x = -x;
     450    }
     451
     452    /* Normalise x so that mantissa is in [1..9.999] */
     453    int exponent = 0;
     454    for (real div = r1, newdiv; true; div = newdiv)
     455    {
     456        newdiv = div * r10;
     457        if (x < newdiv)
     458        {
     459            x /= div;
     460            break;
     461        }
     462        exponent++;
     463    }
     464    for (real mul = 1, newx; true; mul *= r10)
     465    {
     466        newx = x * mul;
     467        if (newx >= r1)
     468        {
     469            x = newx;
     470            break;
     471        }
     472        exponent--;
     473    }
     474
     475    /* Print digits */
     476    for (int i = 0; i < 150; i++)
     477    {
     478        int digit = (int)x;
     479        printf("%i", digit);
     480        if (i == 0)
     481            printf(".");
     482        x -= real(digit);
     483        x *= r10;
     484    }
     485
     486    /* Print exponent information */
     487    if (exponent < 0)
     488        printf("e-%i", -exponent);
     489    else if (exponent > 0)
     490        printf("e+%i", exponent);
     491
    413492    printf("\n");
    414493}
  • trunk/src/real.h

    r976 r983  
    2828public:
    2929    inline real() { }
     30
    3031    real(float f);
    3132    real(double f);
     33    real(int i);
     34    real(unsigned int i);
    3235
    3336    operator float() const;
    3437    operator double() const;
     38    operator int() const;
     39    operator unsigned int() const;
    3540
    3641    real operator -() const;
     
    3944    real operator *(real const &x) const;
    4045    real operator /(real const &x) const;
     46    real &operator +=(real const &x);
     47    real &operator -=(real const &x);
     48    real &operator *=(real const &x);
     49    real &operator /=(real const &x);
    4150
     51    bool operator ==(real const &x) const;
     52    bool operator !=(real const &x) const;
    4253    bool operator <(real const &x) const;
    4354    bool operator >(real const &x) const;
Note: See TracChangeset for help on using the changeset viewer.