Changeset 976
- Timestamp:
- Sep 22, 2011, 6:16:51 PM (11 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/real.cpp
r975 r976 25 25 real::real(float f) 26 26 { 27 union { float f; uint32_t x; } u = { f }; 28 29 uint32_t sign = u.x & 0x80000000u; 30 uint32_t exponent = (u.x >> 23) & 0xff; 27 new(this) real((double)f); 28 } 29 30 real::real(double d) 31 { 32 union { double d; uint64_t x; } u = { d }; 33 34 uint32_t sign = (u.x >> 63) << 31; 35 uint32_t exponent = (u.x << 1) >> 53; 31 36 32 37 switch (exponent) 33 38 { 34 39 case 0x00: 35 case 0xff: 36 m_signexp = sign | exponent; 40 m_signexp = sign; 41 break; 42 case 0x7ff: 43 m_signexp = sign | 0x7fffffffu; 37 44 break; 38 45 default: 39 m_signexp = sign | (exponent + (1 << 30) - (1 << 7));46 m_signexp = sign | (exponent + (1 << 30) - (1 << 10)); 40 47 break; 41 48 } 42 49 43 m_mantissa[0] = u.x >> 7; 44 m_mantissa[1] = u.x << 9; 45 memset(m_mantissa + 2, 0, sizeof(m_mantissa) - sizeof(m_mantissa[0])); 50 m_mantissa[0] = u.x >> 36; 51 m_mantissa[1] = u.x >> 20; 52 m_mantissa[2] = u.x >> 4; 53 m_mantissa[3] = u.x << 12; 54 memset(m_mantissa + 4, 0, sizeof(m_mantissa) - 4 * sizeof(m_mantissa[0])); 46 55 } 47 56 48 57 real::operator float() const 49 58 { 50 union { float f; uint32_t x; } u; 51 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)exponent - (1 << 30) + (1 << 7); 59 return (float)(double)(*this); 60 } 61 62 real::operator double() const 63 { 64 union { double d; uint64_t x; } u; 65 66 /* Get sign */ 67 u.x = m_signexp >> 31; 68 u.x <<= 11; 69 70 /* Compute new exponent */ 71 uint32_t exponent = (m_signexp << 1) >> 1; 72 int e = (int)exponent - (1 << 30) + (1 << 10); 57 73 58 74 if (e < 0) 59 u.x = sign; 60 else if (e >= 0xff) 61 u.x = sign | (0xff << 23); 75 u.x <<= 52; 76 else if (e >= 0x7ff) 77 { 78 u.x |= 0x7ff; 79 u.x <<= 52; 80 } 62 81 else 63 u.x = sign | (e << 23) | mantissa; 64 65 return u.f; 82 { 83 u.x |= e; 84 85 /* Store mantissa if necessary */ 86 u.x <<= 16; 87 u.x |= m_mantissa[0]; 88 u.x <<= 16; 89 u.x |= m_mantissa[1]; 90 u.x <<= 16; 91 u.x |= m_mantissa[2]; 92 u.x <<= 4; 93 u.x |= m_mantissa[3] >> 12; 94 } 95 96 return u.d; 66 97 } 67 98 -
trunk/src/real.h
r975 r976 29 29 inline real() { } 30 30 real(float f); 31 real(double f); 31 32 32 33 operator float() const; 34 operator double() const; 33 35 34 36 real operator -() const; -
trunk/test/unit/real.cpp
r975 r976 30 30 float a4 = real(-1.0f); 31 31 float a5 = real(1.5f); 32 float a6 = real(12345678.0f); 32 33 33 34 LOLUNIT_ASSERT_EQUAL(a1, 0.0f); … … 36 37 LOLUNIT_ASSERT_EQUAL(a4, -1.0f); 37 38 LOLUNIT_ASSERT_EQUAL(a5, 1.5f); 39 LOLUNIT_ASSERT_EQUAL(a6, 12345678.0f); 40 } 41 42 LOLUNIT_TEST(test_real_from_double) 43 { 44 double a1 = real(0.0); 45 double a2 = real(-0.0); 46 double a3 = real(1.0); 47 double a4 = real(-1.0); 48 double a5 = real(1.5); 49 double a6 = real(1234567876543210.0); 50 51 LOLUNIT_ASSERT_DOUBLES_EQUAL(a1, 0.0, 0.0); 52 LOLUNIT_ASSERT_DOUBLES_EQUAL(a2, -0.0, 0.0); 53 LOLUNIT_ASSERT_DOUBLES_EQUAL(a3, 1.0, 0.0); 54 LOLUNIT_ASSERT_DOUBLES_EQUAL(a4, -1.0, 0.0); 55 LOLUNIT_ASSERT_DOUBLES_EQUAL(a5, 1.5, 0.0); 56 LOLUNIT_ASSERT_DOUBLES_EQUAL(a6, 1234567876543210.0, 0.0); 38 57 } 39 58
Note: See TracChangeset
for help on using the changeset viewer.