Changeset 971


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

core: handle zero, negative zero and infinite in the real constructor,
and add a test suite check for unary minus.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/real.cpp

    r970 r971  
    2828
    2929    uint32_t sign = u.x & 0x80000000u;
    30     int e = ((u.x >> 23) & 0xff) + (1 << 30) - (1 << 7);
     30    uint32_t exponent = (u.x >> 23) & 0xff;
    3131
    32     m_signexp = sign | e;
     32    switch (exponent)
     33    {
     34    case 0x00:
     35    case 0xff:
     36        m_signexp = sign | exponent;
     37        break;
     38    default:
     39        m_signexp = sign | (exponent + (1 << 30) - (1 << 7));
     40        break;
     41    }
     42
    3343    m_mantissa[0] = u.x >> 7;
    3444    m_mantissa[1] = u.x << 9;
     
    4050    union { float f; uint32_t x; } u;
    4151
    42     u.x = m_mantissa[0] << 7;
    43     u.x |= m_mantissa[1] >> 9;
    44     u.x |= ((m_signexp & 0x7fffffffu) - (1 << 30) + (1 << 7)) << 23;
    45     u.x |= m_signexp & 0x80000000u;
     52    uint32_t sign = m_signexp & 0x80000000u;
     53    uint32_t exponent = m_signexp & 0x7fffffffu;
     54    uint32_t mantissa = (m_mantissa[0] << 7) | (m_mantissa[1] >> 9);
     55
     56    int e = (int)(m_signexp & 0x7fffffffu) - (1 << 30) + (1 << 7);
     57
     58    if (e < 0)
     59        u.x = sign;
     60    else if (e >= 0xff)
     61        u.x = sign | (0xff << 23);
     62    else
     63        u.x = sign | (e << 23) | mantissa;
    4664
    4765    return u.f;
     
    5876    if ((m_signexp << 1) < (x.m_signexp << 1))
    5977        return x + *this;
     78
     79    if (x.m_signexp << 1 == 0)
     80        return *this;
    6081
    6182    /* For now, assume both numbers are positive. */
  • trunk/test/unit/real.cpp

    r970 r971  
    2626    LOLUNIT_TEST(test_real_from_float)
    2727    {
    28         float x = real(0.0f);
    29         float y = real(1.0f);
    30         float z = real(1.5f);
     28        float a1 = real(0.0f);
     29        float a2 = real(-0.0f);
     30        float a3 = real(1.0f);
     31        float a4 = real(-1.0f);
     32        float a5 = real(1.5f);
    3133
    32         LOLUNIT_ASSERT_EQUAL(x, 0.0f);
    33         LOLUNIT_ASSERT_EQUAL(y, 1.0f);
    34         LOLUNIT_ASSERT_EQUAL(z, 1.5f);
     34        LOLUNIT_ASSERT_EQUAL(a1, 0.0f);
     35        LOLUNIT_ASSERT_EQUAL(a2, -0.0f);
     36        LOLUNIT_ASSERT_EQUAL(a3, 1.0f);
     37        LOLUNIT_ASSERT_EQUAL(a4, -1.0f);
     38        LOLUNIT_ASSERT_EQUAL(a5, 1.5f);
     39    }
     40
     41    LOLUNIT_TEST(test_real_neg)
     42    {
     43        float a1 = - real(1.0f);
     44        float a2 = - real(-1.0f);
     45        float a3 = - real(0.0f);
     46        float a4 = - real(-0.0f);
     47
     48        LOLUNIT_ASSERT_EQUAL(a1, -1.0f);
     49        LOLUNIT_ASSERT_EQUAL(a2, 1.0f);
     50        LOLUNIT_ASSERT_EQUAL(a3, -0.0f);
     51        LOLUNIT_ASSERT_EQUAL(a4, 0.0f);
    3552    }
    3653
Note: See TracChangeset for help on using the changeset viewer.