diff --git a/src/real.cpp b/src/real.cpp
index f7dfb45d..709d4082 100644
--- a/src/real.cpp
+++ b/src/real.cpp
@@ -27,9 +27,19 @@ real::real(float f)
     union { float f; uint32_t x; } u = { f };
 
     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[1] = u.x << 9;
     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;
 
-    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;
 }
@@ -58,6 +76,9 @@ real real::operator +(real const &x) const
     if ((m_signexp << 1) < (x.m_signexp << 1))
         return x + *this;
 
+    if (x.m_signexp << 1 == 0)
+        return *this;
+
     /* For now, assume both numbers are positive. */
     real ret;
 
diff --git a/test/unit/real.cpp b/test/unit/real.cpp
index d5ab66ab..f03b5f50 100644
--- a/test/unit/real.cpp
+++ b/test/unit/real.cpp
@@ -25,13 +25,30 @@ LOLUNIT_FIXTURE(RealTest)
 public:
     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)