Changeset 972


Ignore:
Timestamp:
Sep 22, 2011, 9:15:59 AM (11 years ago)
Author:
sam
Message:

core: fix real unary minus and handle negative numbers in additions.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/real.cpp

    r971 r972  
    5454    uint32_t mantissa = (m_mantissa[0] << 7) | (m_mantissa[1] >> 9);
    5555
    56     int e = (int)(m_signexp & 0x7fffffffu) - (1 << 30) + (1 << 7);
     56    int e = (int)exponent - (1 << 30) + (1 << 7);
    5757
    5858    if (e < 0)
     
    6666}
    6767
    68 real real::operator -()
    69 {
    70     m_signexp ^= 0x80000000u;
    71     return *this;
     68real real::operator -() const
     69{
     70    real ret = *this;
     71    ret.m_signexp ^= 0x80000000u;
     72    return ret;
    7273}
    7374
    7475real real::operator +(real const &x) const
    7576{
     77    if (x.m_signexp << 1 == 0)
     78        return *this;
     79
     80    /* Ensure *this is the larger exponent, and both arguments are
     81     * positive (otherwise, switch signs, or replace + with -). */
    7682    if ((m_signexp << 1) < (x.m_signexp << 1))
    7783        return x + *this;
    7884
    79     if (x.m_signexp << 1 == 0)
    80         return *this;
    81 
    82     /* For now, assume both numbers are positive. */
     85    if (m_signexp >> 31)
     86        return -(-*this + -x);
     87
     88    if (x.m_signexp >> 31)
     89        return *this - x;
     90
    8391    real ret;
    8492
    85     int e1 = (m_signexp & 0x7fffffffu) - (1 << 30) + 1;
    86     int e2 = (x.m_signexp & 0x7fffffffu) - (1 << 30) + 1;
     93    int e1 = m_signexp - (1 << 30) + 1;
     94    int e2 = x.m_signexp - (1 << 30) + 1;
    8795
    8896    int bigoff = (e1 - e2) / (sizeof(uint16_t) * 8);
     
    92100
    93101    uint32_t carry = 0;
    94     for (int i = 0; i < BIGITS; i++)
    95     {
    96         carry = m_mantissa[BIGITS - 1 - i];
    97         if (BIGITS - 1 - i - bigoff >= 0)
    98             carry += x.m_mantissa[BIGITS - 1 - i - bigoff] >> off;
    99         else if (BIGITS - 1 - i - bigoff == -1)
     102    for (int i = BIGITS; i--; )
     103    {
     104        carry = m_mantissa[i];
     105        if (i - bigoff >= 0)
     106            carry += x.m_mantissa[i - bigoff] >> off;
     107        else if (i - bigoff == -1)
    100108            carry += 0x0001u >> off;
    101109
    102         if (BIGITS - 1 - i - bigoff - 1 >= 0)
    103             carry += (x.m_mantissa[BIGITS - 1 - i - bigoff - 1] << (16 - off)) & 0xffffu;
    104         else if (BIGITS - 1 - i - bigoff - 1 == -1)
     110        if (i - bigoff > 0)
     111            carry += (x.m_mantissa[i - bigoff - 1] << (16 - off)) & 0xffffu;
     112        else if (i - bigoff == 0)
    105113            carry += 0x0001u << (16 - off);
    106114
    107         ret.m_mantissa[BIGITS - 1 - i] = carry;
     115        ret.m_mantissa[i] = carry;
    108116        carry >>= 16;
    109117    }
     
    125133}
    126134
     135real real::operator -(real const &x) const
     136{
     137    if (x.m_signexp << 1 == 0)
     138        return *this;
     139
     140    /* Ensure *this is the larger exponent, and both arguments are
     141     * positive (otherwise, switch signs, or replace - with +). */
     142    if ((m_signexp << 1) < (x.m_signexp << 1))
     143        return -(x - *this);
     144
     145    if (m_signexp >> 31)
     146        return -(-*this + x);
     147
     148    if (x.m_signexp >> 31)
     149        return (*this) + (-x);
     150
     151    real ret;
     152
     153    return ret;
     154}
     155
    127156real real::operator *(real const &x) const
    128157{
  • trunk/src/real.h

    r970 r972  
    3131
    3232    operator float() const;
    33     real operator -();
     33    real operator -() const;
    3434    real operator +(real const &x) const;
     35    real operator -(real const &x) const;
    3536    real operator *(real const &x) const;
    3637
  • trunk/test/unit/real.cpp

    r971 r972  
    2323LOLUNIT_FIXTURE(RealTest)
    2424{
    25 public:
    2625    LOLUNIT_TEST(test_real_from_float)
    2726    {
     
    5453    LOLUNIT_TEST(test_real_add)
    5554    {
     55        float a1 = real(1.0f) + real(0.0f);
     56        float a2 = real(0.0f) + real(1.0f);
     57        float a3 = real(1.0f) + real(1.0f);
     58        float a4 = real(-1.0f) + real(-1.0f);
     59        float a5 = real(1.0f) + real(0.125f);
     60
     61        LOLUNIT_ASSERT_EQUAL(a1, 1.0f);
     62        LOLUNIT_ASSERT_EQUAL(a2, 1.0f);
     63        LOLUNIT_ASSERT_EQUAL(a3, 2.0f);
     64        LOLUNIT_ASSERT_EQUAL(a4, -2.0f);
     65        LOLUNIT_ASSERT_EQUAL(a5, 1.125f);
     66    }
     67
     68    LOLUNIT_TEST(test_real_sub)
     69    {
     70#if 0
     71printf("\n");
     72real k(1.25f);
     73k.print();
     74real l(1.0f);
     75l.print();
     76real m = k - l;
     77m.print();
     78#endif
    5679        LOLUNIT_ASSERT(true);
    5780    }
Note: See TracChangeset for help on using the changeset viewer.