diff --git a/src/Makefile.am b/src/Makefile.am
index 646a1dc..b7abfaa 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,5 +16,5 @@ include_HEADERS = body.h frame.h generic_system_view.h glfreetype.h gui_button.h
 		gui_radio_group.h gui_screen.h gui_toggle_button.h gui_widget.h libs.h matrix4x4.h mtrand.h objimport.h l3d.h \
 		planet.h player.h dynamic_body.h sector.h sector_view.h ship_cpanel.h ship.h space.h star.h star_system.h system_info_view.h \
 		system_view.h vector3.h view.h world_view.h date.h space_station.h space_station_view.h model_body.h gui_iselectable.h \
-		ship_type.h object.h info_view.h model_coll_mesh_data.h object_viewer_view.h
+		ship_type.h object.h info_view.h model_coll_mesh_data.h object_viewer_view.h fixed.h
 
diff --git a/src/fixed.h b/src/fixed.h
new file mode 100644
index 0000000..98b8e02
--- /dev/null
+++ b/src/fixed.h
@@ -0,0 +1,56 @@
+#pragma once
+#include <SDL_stdinc.h>
+
+class fixed {
+public:
+  enum { FRAC = 16 };
+  fixed(void) : v(0) {}
+  fixed(int raw) : v(raw) {}
+  fixed(int num, int denom) : v(((Sint64)num<<FRAC) / (Sint64)denom) {}
+
+  friend fixed operator+(const fixed a, const int b) { return a+fixed(b<<FRAC); }
+  friend fixed operator-(const fixed a, const int b) { return a-fixed(b<<FRAC); }
+  friend fixed operator*(const fixed a, const int b) { return a*fixed(b<<FRAC); }
+  friend fixed operator/(const fixed a, const int b) { return a/fixed(b<<FRAC); }
+  friend fixed operator+(const int a, const fixed b) { return fixed(a<<FRAC)+b; }
+  friend fixed operator-(const int a, const fixed b) { return fixed(a<<FRAC)-b; }
+  friend fixed operator*(const int a, const fixed b) { return fixed(a<<FRAC)*b; }
+  friend fixed operator/(const int a, const fixed b) { return fixed(a<<FRAC)/b; }
+
+  friend bool operator==(const fixed a, const int b) { return a == fixed(b<<FRAC); }
+  friend bool operator==(const int a, const fixed b) { return b == fixed(a<<FRAC); }
+  friend bool operator>=(const fixed a, const int b) { return a >= fixed(b<<FRAC); }
+  friend bool operator>=(const int a, const fixed b) { return b >= fixed(a<<FRAC); }
+  friend bool operator<=(const fixed a, const int b) { return a <= fixed(b<<FRAC); }
+  friend bool operator<=(const int a, const fixed b) { return b <= fixed(a<<FRAC); }
+
+  friend bool operator>(const fixed a, const int b) { return a > fixed(b<<FRAC); }
+  friend bool operator>(const int a, const fixed b) { return b > fixed(a<<FRAC); }
+  friend bool operator<(const fixed a, const int b) { return a < fixed(b<<FRAC); }
+  friend bool operator<(const int a, const fixed b) { return b < fixed(a<<FRAC); }
+
+  fixed &operator*=(const fixed a)  { (*this) = (*this)*a; return (*this); }
+  fixed &operator*=(const int a)    { (*this) = (*this)*a; return (*this); }
+  fixed &operator/=(const fixed a)  { (*this) = (*this)/a; return (*this); }
+  fixed &operator/=(const int a)    { (*this) = (*this)/a; return (*this); }
+  fixed &operator+=(const fixed a)  { (*this) = (*this)+a; return (*this); }
+  fixed &operator+=(const int a)    { (*this) = (*this)+a; return (*this); }
+  fixed &operator-=(const fixed a)  { (*this) = (*this)-a; return (*this); }
+  fixed &operator-=(const int a)    { (*this) = (*this)-a; return (*this); }
+
+  friend fixed operator+(const fixed a, const fixed b) { return fixed(a.v+b.v); }
+  friend fixed operator-(const fixed a, const fixed b) { return fixed(a.v-b.v); }
+  friend fixed operator*(const fixed a, const fixed b) { return fixed(((Sint64)a.v*(Sint64)b.v)>>FRAC); }
+  friend fixed operator/(const fixed a, const fixed b) { return fixed(((Sint64)a.v<<FRAC)/(Sint64)b.v); }
+  friend bool operator==(const fixed a, const fixed b) { return a.v == b.v; }
+  friend bool operator>(const fixed a, const fixed b)  { return a.v > b.v;  }
+  friend bool operator<(const fixed a, const fixed b)  { return a.v < b.v;  }
+  friend bool operator>=(const fixed a, const fixed b) { return a.v >= b.v; }
+  friend bool operator<=(const fixed a, const fixed b) { return a.v <= b.v; }
+
+  operator float(void)  { return v/(float)(1<<FRAC); }
+  operator double(void) { return v/(double)(1<<FRAC); }
+private:
+  int v;
+};
+
diff --git a/src/libs.h b/src/libs.h
index aa24c19..6bf5353 100644
--- a/src/libs.h
+++ b/src/libs.h
@@ -15,6 +15,7 @@
 #define alloca _alloca
 #endif
 
+#include "fixed.h"
 #include "vector3.h"
 #include "matrix4x4.h"
 #include "mtrand.h"
diff --git a/src/mtrand.h b/src/mtrand.h
index a7970e0..aabc843 100644
--- a/src/mtrand.h
+++ b/src/mtrand.h
@@ -1,5 +1,5 @@
 #pragma once
-
+#include "fixed.h"
 /* Mersenne Twister rng. */
 class MTRand_int32 {
 public:
@@ -61,7 +61,7 @@ public:
 
   double NDouble(int p) {
     double o = Double(1.0);
-    while(--p) o *= Double(1.0);
+    while(--p > 0) o *= Double(1.0);
     return o;
   }
 
@@ -98,6 +98,15 @@ public:
     return (static_cast<double>(rand_int32() >> 5) * 67108864. +
         static_cast<double>(rand_int32() >> 6)) * (1./9007199254740992.);
   }
+  /* [0,1] */
+  fixed Fixed(void) {
+    return fixed(rand_int32() >> fixed::FRAC);
+  }
+  fixed NFixed(int p) {
+    fixed o(1 << fixed::FRAC);
+    while(--p > 0) o*= Fixed();
+    return o;
+  }
   /* [min,max] */
   unsigned int Int32(int min, int max) {
     return (rand_int32()%(1+max-min))+min;