Преглед изворни кода

core: handle zero, negative zero and infinite in the real constructor,

and add a test suite check for unary minus.
legacy
Sam Hocevar sam пре 13 година
родитељ
комит
884978c71b
2 измењених фајлова са 50 додато и 12 уклоњено
  1. +27
    -6
      src/real.cpp
  2. +23
    -6
      test/unit/real.cpp

+ 27
- 6
src/real.cpp Прегледај датотеку

@@ -27,9 +27,19 @@ real::real(float f)
union { float f; uint32_t x; } u = { f }; union { float f; uint32_t x; } u = { f };


uint32_t sign = u.x & 0x80000000u; uint32_t sign = u.x & 0x80000000u;
int e = ((u.x >> 23) & 0xff) + (1 << 30) - (1 << 7);
uint32_t exponent = (u.x >> 23) & 0xff;

switch (exponent)
{
case 0x00:
case 0xff:
m_signexp = sign | exponent;
break;
default:
m_signexp = sign | (exponent + (1 << 30) - (1 << 7));
break;
}


m_signexp = sign | e;
m_mantissa[0] = u.x >> 7; m_mantissa[0] = u.x >> 7;
m_mantissa[1] = u.x << 9; m_mantissa[1] = u.x << 9;
memset(m_mantissa + 2, 0, sizeof(m_mantissa) - sizeof(m_mantissa[0])); memset(m_mantissa + 2, 0, sizeof(m_mantissa) - sizeof(m_mantissa[0]));
@@ -39,10 +49,18 @@ real::operator float() const
{ {
union { float f; uint32_t x; } u; union { float f; uint32_t x; } u;


u.x = m_mantissa[0] << 7;
u.x |= m_mantissa[1] >> 9;
u.x |= ((m_signexp & 0x7fffffffu) - (1 << 30) + (1 << 7)) << 23;
u.x |= m_signexp & 0x80000000u;
uint32_t sign = m_signexp & 0x80000000u;
uint32_t exponent = m_signexp & 0x7fffffffu;
uint32_t mantissa = (m_mantissa[0] << 7) | (m_mantissa[1] >> 9);

int e = (int)(m_signexp & 0x7fffffffu) - (1 << 30) + (1 << 7);

if (e < 0)
u.x = sign;
else if (e >= 0xff)
u.x = sign | (0xff << 23);
else
u.x = sign | (e << 23) | mantissa;


return u.f; return u.f;
} }
@@ -58,6 +76,9 @@ real real::operator +(real const &x) const
if ((m_signexp << 1) < (x.m_signexp << 1)) if ((m_signexp << 1) < (x.m_signexp << 1))
return x + *this; return x + *this;


if (x.m_signexp << 1 == 0)
return *this;

/* For now, assume both numbers are positive. */ /* For now, assume both numbers are positive. */
real ret; real ret;




+ 23
- 6
test/unit/real.cpp Прегледај датотеку

@@ -25,13 +25,30 @@ LOLUNIT_FIXTURE(RealTest)
public: public:
LOLUNIT_TEST(test_real_from_float) LOLUNIT_TEST(test_real_from_float)
{ {
float x = real(0.0f);
float y = real(1.0f);
float z = real(1.5f);
float a1 = real(0.0f);
float a2 = real(-0.0f);
float a3 = real(1.0f);
float a4 = real(-1.0f);
float a5 = real(1.5f);


LOLUNIT_ASSERT_EQUAL(x, 0.0f);
LOLUNIT_ASSERT_EQUAL(y, 1.0f);
LOLUNIT_ASSERT_EQUAL(z, 1.5f);
LOLUNIT_ASSERT_EQUAL(a1, 0.0f);
LOLUNIT_ASSERT_EQUAL(a2, -0.0f);
LOLUNIT_ASSERT_EQUAL(a3, 1.0f);
LOLUNIT_ASSERT_EQUAL(a4, -1.0f);
LOLUNIT_ASSERT_EQUAL(a5, 1.5f);
}

LOLUNIT_TEST(test_real_neg)
{
float a1 = - real(1.0f);
float a2 = - real(-1.0f);
float a3 = - real(0.0f);
float a4 = - real(-0.0f);

LOLUNIT_ASSERT_EQUAL(a1, -1.0f);
LOLUNIT_ASSERT_EQUAL(a2, 1.0f);
LOLUNIT_ASSERT_EQUAL(a3, -0.0f);
LOLUNIT_ASSERT_EQUAL(a4, 0.0f);
} }


LOLUNIT_TEST(test_real_add) LOLUNIT_TEST(test_real_add)


Loading…
Откажи
Сачувај