@@ -17,9 +17,9 @@ | |||
#define __LOL_CORE_H__ | |||
// Base types | |||
#include "half.h" | |||
#include "matrix.h" | |||
#include "numeric.h" | |||
#include "half.h" | |||
#include "timer.h" | |||
// Static classes | |||
@@ -63,6 +63,26 @@ public: | |||
operator float() const; | |||
inline operator int() const { return (int)(float)*this; } | |||
/* Operations */ | |||
inline half operator -() { return makebits(m_bits ^ 0x8000u); } | |||
inline half &operator +=(float f) { return (*this = (half)(*this + f)); } | |||
inline half &operator -=(float f) { return (*this = (half)(*this - f)); } | |||
inline half &operator *=(float f) { return (*this = (half)(*this * f)); } | |||
inline half &operator /=(float f) { return (*this = (half)(*this / f)); } | |||
inline half &operator +=(half h) { return (*this = (half)(*this + h)); } | |||
inline half &operator -=(half h) { return (*this = (half)(*this - h)); } | |||
inline half &operator *=(half h) { return (*this = (half)(*this * h)); } | |||
inline half &operator /=(half h) { return (*this = (half)(*this / h)); } | |||
inline float operator +(float f) const { return (float)*this + f; } | |||
inline float operator -(float f) const { return (float)*this - f; } | |||
inline float operator *(float f) const { return (float)*this * f; } | |||
inline float operator /(float f) const { return (float)*this / f; } | |||
inline float operator +(half h) const { return (float)*this + (float)h; } | |||
inline float operator -(half h) const { return (float)*this - (float)h; } | |||
inline float operator *(half h) const { return (float)*this * (float)h; } | |||
inline float operator /(half h) const { return (float)*this / (float)h; } | |||
/* Factories */ | |||
static half makeslow(float f); | |||
static half makefast(float f); | |||
@@ -74,6 +94,16 @@ public: | |||
} | |||
}; | |||
inline float &operator +=(float &f, half h) { return f += (float)h; } | |||
inline float &operator -=(float &f, half h) { return f -= (float)h; } | |||
inline float &operator *=(float &f, half h) { return f *= (float)h; } | |||
inline float &operator /=(float &f, half h) { return f /= (float)h; } | |||
inline float operator +(float f, half h) { return f + (float)h; } | |||
inline float operator -(float f, half h) { return f - (float)h; } | |||
inline float operator *(float f, half h) { return f * (float)h; } | |||
inline float operator /(float f, half h) { return f / (float)h; } | |||
} /* namespace lol */ | |||
#endif // __LOL_HALF_H__ | |||
@@ -35,6 +35,8 @@ class HalfTest : public CppUnit::TestCase | |||
CPPUNIT_TEST(test_half_classify); | |||
CPPUNIT_TEST(test_half_to_float); | |||
CPPUNIT_TEST(test_half_to_int); | |||
CPPUNIT_TEST(test_float_op_half); | |||
CPPUNIT_TEST(test_half_op_float); | |||
CPPUNIT_TEST_SUITE_END(); | |||
public: | |||
@@ -207,6 +209,89 @@ public: | |||
CPPUNIT_ASSERT_EQUAL((int)(half)(-65504.0f), -65504); | |||
} | |||
void test_float_op_half() | |||
{ | |||
half zero = 0; | |||
half one = 1; | |||
half two = 2; | |||
float a = zero + one; | |||
CPPUNIT_ASSERT_EQUAL(1.0f, a); | |||
a += zero; | |||
CPPUNIT_ASSERT_EQUAL(1.0f, a); | |||
a -= zero; | |||
CPPUNIT_ASSERT_EQUAL(1.0f, a); | |||
a *= one; | |||
CPPUNIT_ASSERT_EQUAL(1.0f, a); | |||
a /= one; | |||
CPPUNIT_ASSERT_EQUAL(1.0f, a); | |||
float b = one + zero; | |||
CPPUNIT_ASSERT_EQUAL(1.0f, b); | |||
b += one; | |||
CPPUNIT_ASSERT_EQUAL(2.0f, b); | |||
b *= two; | |||
CPPUNIT_ASSERT_EQUAL(4.0f, b); | |||
b -= two; | |||
CPPUNIT_ASSERT_EQUAL(2.0f, b); | |||
b /= two; | |||
CPPUNIT_ASSERT_EQUAL(1.0f, b); | |||
float c = one - zero; | |||
CPPUNIT_ASSERT_EQUAL(1.0f, c); | |||
float d = two - one; | |||
CPPUNIT_ASSERT_EQUAL(1.0f, d); | |||
float e = two + (-one); | |||
CPPUNIT_ASSERT_EQUAL(1.0f, e); | |||
float f = (two * two) / (one + one); | |||
CPPUNIT_ASSERT_EQUAL(2.0f, f); | |||
} | |||
void test_half_op_float() | |||
{ | |||
half zero = 0; | |||
half one = 1; | |||
half two = 2; | |||
half four = 4; | |||
half a = one + 0.0f; | |||
CPPUNIT_ASSERT_EQUAL(one.bits(), a.bits()); | |||
a += 0.0f; | |||
CPPUNIT_ASSERT_EQUAL(one.bits(), a.bits()); | |||
a -= 0.0f; | |||
CPPUNIT_ASSERT_EQUAL(one.bits(), a.bits()); | |||
a *= 1.0f; | |||
CPPUNIT_ASSERT_EQUAL(one.bits(), a.bits()); | |||
a /= 1.0f; | |||
CPPUNIT_ASSERT_EQUAL(one.bits(), a.bits()); | |||
half b = one + 0.0f; | |||
CPPUNIT_ASSERT_EQUAL(one.bits(), b.bits()); | |||
b += 1.0f; | |||
CPPUNIT_ASSERT_EQUAL(two.bits(), b.bits()); | |||
b *= 2.0f; | |||
CPPUNIT_ASSERT_EQUAL(four.bits(), b.bits()); | |||
b -= 2.0f; | |||
CPPUNIT_ASSERT_EQUAL(two.bits(), b.bits()); | |||
b /= 2.0f; | |||
CPPUNIT_ASSERT_EQUAL(one.bits(), b.bits()); | |||
half c = 1.0f - zero; | |||
CPPUNIT_ASSERT_EQUAL(one.bits(), c.bits()); | |||
half d = 2.0f - one; | |||
CPPUNIT_ASSERT_EQUAL(one.bits(), d.bits()); | |||
half e = 2.0f + (-one); | |||
CPPUNIT_ASSERT_EQUAL(one.bits(), e.bits()); | |||
half f = (2.0f * two) / (1.0f + one); | |||
CPPUNIT_ASSERT_EQUAL(two.bits(), f.bits()); | |||
} | |||
private: | |||
struct TestPair { float f; uint16_t x; }; | |||