--- /dev/null
+#ifndef MATH_FIXED_H_
+#define MATH_FIXED_H_
+
+#include "utility.h"
+
+#include <cmath>
+#include <limits>
+#include <ostream>
+#include <SDL.h>
+
+
+namespace math {
+
+/// Fixed point number type.
+/// The first bit is used for the sign (0 = positive, 1 = negative), the last
+/// fracBits bits are used for the fractional part and the remaining middle
+/// bits represent the integer value.
+/// The sign bit of zero is undefined.
+template<Uint8 fracBits>
+class Fixed {
+
+template<Uint8>
+friend class Fixed;
+
+public:
+       /// Create a fixed point decimal representing i/f .
+       Fixed(Sint32 i = 0, Uint32 f = 1)
+       : rep(((i < 0 ? (i * -1) : i) << IntShift()) & IntMask()) {
+               rep /= f;
+               if (i < 0) {
+                       rep |= SignMask();
+               }
+       }
+       explicit Fixed(double d)
+       : rep(0) {
+               rep = std::abs(d) * (1 << IntShift());
+               if (d < 0) {
+                       rep |= SignMask();
+               }
+       }
+       template<Uint8 otherFrac>
+       explicit Fixed(const Fixed<otherFrac> &other)
+       : rep(0) {
+               Uint32 otherInt = other.RawInt();
+               rep = DistanceShift(otherInt, fracBits, otherFrac);
+               if (other.Sigma() < 0) {
+                       rep |= SignMask();
+               }
+       }
+
+public:
+       int Int() const { return IntPart() * Sigma(); }
+       int Sigma() const {
+               if (IntPart() == 0 && FracPart() == 0) {
+                       return 0;
+               } else if (SignPart() == 0) {
+                       return 1;
+               } else {
+                       return -1;
+               }
+       }
+       double Double() const { return double(SignedInt()) / (1 << IntShift()); }
+
+public:
+       bool operator ==(const Fixed &other) const {
+               return rep == other.rep;
+       }
+       bool operator !=(const Fixed &other) const {
+               return rep != other.rep;
+       }
+       bool operator <(const Fixed &other) const {
+               return SignedInt() < other.SignedInt();
+       }
+       bool operator <=(const Fixed &other) const {
+               return SignedInt() <= other.SignedInt();
+       }
+       bool operator >(const Fixed &other) const {
+               return SignedInt() > other.SignedInt();
+       }
+       bool operator >=(const Fixed &other) const {
+               return SignedInt() >= other.SignedInt();
+       }
+
+       Fixed operator -() const {
+               Fixed neg;
+               neg.rep = rep ^ SignMask();
+               return neg;
+       }
+
+       Fixed &operator +=(const Fixed &other) {
+               Sint32 temp = SignedInt() + other.SignedInt();
+               if (temp < 0) {
+                       rep = (temp * -1) | SignMask();
+               } else {
+                       rep = temp;
+               }
+               return *this;
+       }
+       Fixed &operator +=(int i) {
+               Sint32 temp = SignedInt() + (i << IntShift());
+               if (temp < 0) {
+                       rep = (temp * -1) | SignMask();
+               } else {
+                       rep = temp;
+               }
+               return *this;
+       }
+       Fixed &operator -=(const Fixed &other) {
+               Sint32 temp = SignedInt() - other.SignedInt();
+               if (temp < 0) {
+                       rep = (temp * -1) | SignMask();
+               } else {
+                       rep = temp;
+               }
+               return *this;
+       }
+       Fixed &operator -=(int i) {
+               Sint32 temp = SignedInt() - (i << IntShift());
+               if (temp < 0) {
+                       rep = (temp * -1) | SignMask();
+               } else {
+                       rep = temp;
+               }
+               return *this;
+       }
+       Fixed &operator *=(const Fixed &other) {
+               Sint64 temp = SignedInt();
+               temp *= other.SignedInt();
+               temp /= (1 << IntShift());
+               if (temp < 0) {
+                       rep = (temp * -1) | SignMask();
+               } else {
+                       rep = temp;
+               }
+               return *this;
+       }
+       Fixed &operator *=(int i) {
+               Sint32 temp = SignedInt() * i;
+               if (temp < 0) {
+                       rep = (temp * -1) | SignMask();
+               } else {
+                       rep = temp;
+               }
+               return *this;
+       }
+       Fixed &operator /=(const Fixed &other) {
+               Sint64 temp = SignedInt();
+               temp *= (1 << IntShift());
+               temp /= other.SignedInt();
+               if (temp < 0) {
+                       rep = (temp * -1) | SignMask();
+               } else {
+                       rep = temp;
+               }
+               return *this;
+       }
+       Fixed &operator /=(int i) {
+               Sint32 temp = SignedInt() / i;
+               if (temp < 0) {
+                       rep = (temp * -1) | SignMask();
+               } else {
+                       rep = temp;
+               }
+               return *this;
+       }
+       Fixed &operator %=(const Fixed &other) {
+               const Uint32 myRaw = RawInt();
+               const Uint32 otherRaw = other.RawInt();
+               const Uint32 intQuotient = myRaw / otherRaw;
+               rep = (myRaw - (otherRaw  * intQuotient)) | (rep & SignMask());
+               return *this;
+       }
+       Fixed &operator %=(int i) {
+               const Uint32 myRaw = RawInt();
+               const Uint32 otherRaw = (i << IntShift());
+               const Uint32 intQuotient = myRaw / otherRaw;
+               rep = (myRaw - (otherRaw  * intQuotient)) | (rep & SignMask());
+               return *this;
+       }
+
+private:
+       int SignBits() const { return 1; }
+       int IntBits() const { return 32 - SignBits() - FracBits(); }
+       int FracBits() const { return fracBits; }
+
+       int SignShift() const { return 31; }
+       int IntShift() const { return fracBits; }
+       int FracShift() const { return 0; }
+
+       Uint32 SignMask() const { return 1 << SignShift(); }
+       Uint32 IntMask() const { return ~(SignMask() | FracMask()); }
+       Uint32 FracMask() const { return (1 << IntShift()) - 1; }
+
+       int SignPart() const { return (rep & SignMask()) >> SignShift(); }
+       int IntPart() const { return (rep & IntMask()) >> IntShift(); }
+       int FracPart() const { return (rep & FracMask()) >> FracShift(); }
+
+       Sint32 SignedInt() const { return Sigma() * RawInt(); }
+       Uint32 RawInt() const { return rep & (~SignMask()); }
+
+private:
+       Uint32 rep;
+
+};
+
+
+template<Uint8 T, Uint8 U>
+inline bool operator ==(const Fixed<T> &lhs, const Fixed<U> &rhs) {
+       if (T < U) {
+               return lhs == Fixed<T>(rhs);
+       } else {
+               return Fixed<U>(lhs) == rhs;
+       }
+}
+
+template<Uint8 T, Uint8 U>
+inline bool operator !=(const Fixed<T> &lhs, const Fixed<U> &rhs) {
+       return !(lhs == rhs);
+}
+
+template<Uint8 T, Uint8 U>
+inline bool operator <(const Fixed<T> &lhs, const Fixed<U> &rhs) {
+       if (T < U) {
+               return lhs < Fixed<T>(rhs);
+       } else {
+               return Fixed<U>(lhs) < rhs;
+       }
+}
+
+template<Uint8 T, Uint8 U>
+inline bool operator <=(const Fixed<T> &lhs, const Fixed<U> &rhs) {
+       if (T < U) {
+               return lhs <= Fixed<T>(rhs);
+       } else {
+               return Fixed<U>(lhs) <= rhs;
+       }
+}
+
+template<Uint8 T, Uint8 U>
+inline bool operator >(const Fixed<T> &lhs, const Fixed<U> &rhs) {
+       return !(lhs <= rhs);
+}
+
+template<Uint8 T, Uint8 U>
+inline bool operator >=(const Fixed<T> &lhs, const Fixed<U> &rhs) {
+       return !(lhs < rhs);
+}
+
+template<Uint8 T, Uint8 U>
+inline Fixed<T> operator +(const Fixed<T> &lhs, const Fixed<U> &rhs) {
+       Fixed<T> temp(lhs);
+       return temp += rhs;
+}
+template<Uint8 T, class Other>
+inline Fixed<T> operator +(const Fixed<T> &lhs, const Other &rhs) {
+       Fixed<T> temp(lhs);
+       return temp += rhs;
+}
+template<Uint8 T, class Other>
+inline Fixed<T> operator +(const Other &lhs, const Fixed<T> &rhs) {
+       return rhs + lhs;
+}
+
+template<Uint8 T, Uint8 U>
+inline Fixed<T> operator -(const Fixed<T> &lhs, const Fixed<U> &rhs) {
+       Fixed<T> temp(lhs);
+       return temp -= rhs;
+}
+template<Uint8 T, class Other>
+inline Fixed<T> operator -(const Fixed<T> &lhs, const Other &rhs) {
+       Fixed<T> temp(lhs);
+       return temp -= rhs;
+}
+template<Uint8 T, class Other>
+inline Fixed<T> operator -(const Other &lhs, const Fixed<T> &rhs) {
+       return lhs + -rhs;
+}
+
+template<Uint8 T, Uint8 U>
+inline Fixed<T> operator *(const Fixed<T> &lhs, const Fixed<U> &rhs) {
+       Fixed<T> temp(lhs);
+       return temp *= rhs;
+}
+template<Uint8 T, class Other>
+inline Fixed<T> operator *(const Fixed<T> &lhs, const Other &rhs) {
+       Fixed<T> temp(lhs);
+       return temp *= rhs;
+}
+template<Uint8 T, class Other>
+inline Fixed<T> operator *(const Other &lhs, const Fixed<T> &rhs) {
+       return rhs * lhs;
+}
+
+template<Uint8 T, Uint8 U>
+inline Fixed<T> operator /(const Fixed<T> &lhs, const Fixed<U> &rhs) {
+       Fixed<T> temp(lhs);
+       return temp /= rhs;
+}
+template<Uint8 T, class Other>
+inline Fixed<T> operator /(const Fixed<T> &lhs, const Other &rhs) {
+       Fixed<T> temp(lhs);
+       return temp /= rhs;
+}
+
+template<Uint8 T, Uint8 U>
+inline Fixed<T> operator %(const Fixed<T> &lhs, const Fixed<U> &rhs) {
+       Fixed<T> temp(lhs);
+       return temp %= rhs;
+}
+template<Uint8 T, class Other>
+inline Fixed<T> operator %(const Fixed<T> &lhs, const Other &rhs) {
+       Fixed<T> temp(lhs);
+       return temp %= rhs;
+}
+
+
+template<Uint8 T>
+inline std::ostream &operator <<(std::ostream &out, const Fixed<T> &f) {
+       return out << f.Double();
+}
+
+}
+
+
+namespace std {
+
+template <Uint8 fracBits>
+class numeric_limits<math::Fixed<fracBits> > {
+
+public:
+       static const bool is_specialized = true;
+       static math::Fixed<fracBits> min() throw() {
+               return max() * -1;
+       }
+       static math::Fixed<fracBits> max() throw() {
+               return math::Fixed<fracBits>(1 << (digits - fracBits) - 1)
+                               + math::Fixed<fracBits>((1 << fracBits) - 2, (1 << fracBits) - 1);
+       }
+       static const int digits = 31;
+       static const int digits10 = 10;
+       static const bool is_signed = true;
+       static const bool is_integer = false;
+       static const bool is_exact = true;
+       static const int radix = 2;
+       static math::Fixed<fracBits> epsilon() throw() {
+               return math::Fixed<fracBits>(1, 1 << (digits - fracBits) - 1);
+       }
+       static math::Fixed<fracBits> round_error() throw() {
+               return epsilon();
+       }
+
+       static const bool is_iec559 = false;
+       static const bool is_bounded = true;
+       static const bool is_modulo = false;
+
+       static const bool traps = false;
+       static const bool tinyness_before = false;
+       static const float_round_style round_style = round_toward_zero;
+};
+
+}
+
+#endif
 
--- /dev/null
+#include "FixedTest.h"
+
+CPPUNIT_TEST_SUITE_REGISTRATION(test_math::FixedTest);
+
+typedef math::Fixed<16> Fixed;
+typedef math::Fixed<8> LowerFixed;
+typedef math::Fixed<24> HigherFixed;
+
+
+namespace test_math {
+
+void FixedTest::setUp() {
+
+}
+
+void FixedTest::tearDown() {
+
+}
+
+
+void FixedTest::testConversion() {
+       CPPUNIT_ASSERT_EQUAL(1, Fixed(3, 2).Int());
+       CPPUNIT_ASSERT_DOUBLES_EQUAL(0.75, Fixed(3, 4).Double(), std::numeric_limits<double>::epsilon());
+
+       CPPUNIT_ASSERT_EQUAL(-1, Fixed(-3, 2).Int());
+       CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.25, Fixed(-5, 4).Double(), std::numeric_limits<double>::epsilon());
+
+       CPPUNIT_ASSERT_EQUAL(Fixed(3, 2), Fixed(1.5));
+       CPPUNIT_ASSERT_EQUAL(Fixed(-4, 10), Fixed(-0.4));
+
+       CPPUNIT_ASSERT_EQUAL(Fixed(3, 2), Fixed(HigherFixed(3, 2)));
+       CPPUNIT_ASSERT_EQUAL(Fixed(3, 2), Fixed(LowerFixed(3, 2)));
+}
+
+void FixedTest::testComparison() {
+       CPPUNIT_ASSERT_EQUAL(Fixed(), Fixed());
+       CPPUNIT_ASSERT_EQUAL(Fixed(1), Fixed(1));
+       CPPUNIT_ASSERT_EQUAL(Fixed(-1), Fixed(-1));
+
+       CPPUNIT_ASSERT_EQUAL(Fixed(1, 2), Fixed(2, 4));
+
+       CPPUNIT_ASSERT(Fixed(0) != Fixed(1));
+       CPPUNIT_ASSERT(Fixed(0) != Fixed(-1));
+       CPPUNIT_ASSERT(Fixed(1, 2) != Fixed(-1, 2));
+
+       CPPUNIT_ASSERT(Fixed(0) < Fixed(1));
+       CPPUNIT_ASSERT(Fixed(1, 2) <= Fixed(1));
+       CPPUNIT_ASSERT(Fixed(0) > Fixed(-1));
+       CPPUNIT_ASSERT(Fixed(1) >= Fixed(-1, 2));
+
+       CPPUNIT_ASSERT(Fixed() == LowerFixed());
+       CPPUNIT_ASSERT(Fixed() == HigherFixed());
+       CPPUNIT_ASSERT(Fixed(1) == LowerFixed(1));
+       CPPUNIT_ASSERT(Fixed(1) == HigherFixed(1));
+       CPPUNIT_ASSERT(Fixed(-1) == LowerFixed(-1));
+       CPPUNIT_ASSERT(Fixed(-1) == HigherFixed(-1));
+
+       CPPUNIT_ASSERT(Fixed(1, 2) == LowerFixed(2, 4));
+       CPPUNIT_ASSERT(Fixed(1, 2) == HigherFixed(2, 4));
+
+       CPPUNIT_ASSERT(Fixed(0) != LowerFixed(1));
+       CPPUNIT_ASSERT(Fixed(0) != HigherFixed(1));
+       CPPUNIT_ASSERT(Fixed(0) != LowerFixed(-1));
+       CPPUNIT_ASSERT(Fixed(0) != HigherFixed(-1));
+       CPPUNIT_ASSERT(Fixed(1, 2) != LowerFixed(-1, 2));
+       CPPUNIT_ASSERT(Fixed(1, 2) != HigherFixed(-1, 2));
+
+       CPPUNIT_ASSERT(Fixed(0) < LowerFixed(1));
+       CPPUNIT_ASSERT(Fixed(0) < HigherFixed(1));
+       CPPUNIT_ASSERT(Fixed(1, 2) <= LowerFixed(1));
+       CPPUNIT_ASSERT(Fixed(1, 2) <= HigherFixed(1));
+       CPPUNIT_ASSERT(Fixed(0) > LowerFixed(-1));
+       CPPUNIT_ASSERT(Fixed(0) > HigherFixed(-1));
+       CPPUNIT_ASSERT(Fixed(1) >= LowerFixed(-1, 2));
+       CPPUNIT_ASSERT(Fixed(1) >= HigherFixed(-1, 2));
+}
+
+void FixedTest::testSum() {
+       CPPUNIT_ASSERT_EQUAL(
+                       Fixed(3, 4),
+                       Fixed(1, 4) + Fixed(1, 2));
+       CPPUNIT_ASSERT_EQUAL(
+                               Fixed(6, 4),
+                               Fixed(2) - Fixed(0.5));
+}
+
+void FixedTest::testProduct() {
+       CPPUNIT_ASSERT_EQUAL(
+                       Fixed(5),
+                       Fixed(2) * Fixed(2.5));
+       CPPUNIT_ASSERT_EQUAL(
+                       Fixed(-1.7499999999),
+                       Fixed(3, 4) * Fixed(-7, 3));
+       CPPUNIT_ASSERT_EQUAL(
+                       Fixed(4),
+                       Fixed(2) / Fixed(0.5));
+       CPPUNIT_ASSERT_EQUAL(
+                       Fixed(3),
+                       Fixed(15) / Fixed(5));
+}
+
+void FixedTest::testModulo() {
+       CPPUNIT_ASSERT_EQUAL(
+                       Fixed(5),
+                       Fixed(5) % 6);
+       CPPUNIT_ASSERT_EQUAL(
+                       Fixed(5),
+                       Fixed(11) % Fixed(6));
+       CPPUNIT_ASSERT_EQUAL(
+                       Fixed(2.5),
+                       Fixed(7.5) % 5);
+       CPPUNIT_ASSERT_EQUAL(
+                       Fixed(0.5),
+                       Fixed(8) % Fixed(7.5));
+}
+
+}