00001
00007 #ifndef __BOUNDEDNUMBER_H__
00008 #define __BOUNDEDNUMBER_H__
00009
00010 #include <cmath>
00011 #include <cassert>
00012 #include <algorithm>
00013
00014 #include "genericalgs.h"
00015
00016
00017
00038 namespace Bounded {
00039
00040
00041
00043 template<class T>
00044 struct Crop { T operator() (T l, T u, T x) { return Generic::crop(l,u,x); } };
00045
00046
00048 template<class T>
00049 struct Wrap { T operator() (T l, T u, T x) { return Generic::wrap(l,u,x); } };
00050
00051
00052
00053
00056 typedef long LargeInt;
00057
00058
00061 typedef double LargeFloat;
00062
00063
00068 typedef double Magnitude;
00069
00070
00071 00072
00073 template<class, LargeInt, LargeInt, class> class Integer;
00074 template<class, LargeInt, LargeInt, class> class Float;
00075
00076
00077
00082 #define MAX_UNSIGNED(T) ((sizeof(T)<<8)-1)
00083
00084
00085
00091 template<class T=unsigned char, LargeInt MaxVal=MAX_UNSIGNED(T),
00092 LargeInt MinVal=0, class Boundary=Crop<LargeInt> >
00093 class Integer {
00094 private:
00095 typedef T value_type;
00096 value_type n;
00097 typedef Integer self;
00098
00099 inline const LargeInt crop(const LargeInt x)
00100 { return Boundary()(Min,Max,x); }
00101
00103 inline value_type set(const LargeInt x)
00104 { return n=value_type(Boundary()(Min,Max,x)); }
00105
00106
00107
00108 public:
00109 static const value_type Min=MinVal;
00110 static const value_type Max=MaxVal;
00112 Integer() : n(set(0)) { }
00113 Integer(value_type val) : n(set(val)) { }
00114 Integer(const self& other)
00115 : n(other.n) { }
00118 template<class OT, LargeInt OMaxVal, LargeInt OMinVal, class OBoundary>
00119 Integer(const Float<OT,OMaxVal,OMinVal,OBoundary>& other)
00120 : n(set(value_type(Max*other.mag()))) { }
00121
00123 void operator= (const LargeInt& val) { set(val); assert(n<=Max); }
00124
00126 self& operator*=(const LargeFloat m) { set(LargeInt(n*m)); return *this; }
00127
00129 self operator+(const self &B) const {
00130 self tmp;
00131 tmp.set(n+B.n);
00132 return tmp;
00133 }
00134
00135
00137 Magnitude mag() const { assert(n<=Max); return LargeFloat(n)/LargeFloat(Max); }
00138
00140 value_type raw() const { assert(n<=Max); return n; }
00141 };
00142
00143
00144
00156 template<class T=float, LargeInt MaxVal=1, LargeInt MinVal=0, class Boundary=Crop<LargeFloat> >
00157 class Float {
00158 private:
00159 typedef T value_type;
00160 value_type n;
00162 inline const LargeFloat crop(const LargeFloat x)
00163 { return Boundary()(Min,Max,x); }
00164
00165 public:
00166 static const value_type Min;
00167 static const value_type Max;
00169 Float() : n(crop(0)) { }
00170 Float(value_type val) : n(crop(val)) { }
00171 Float(const Float<T,MaxVal,MinVal,Boundary>& other)
00172 : n(other.n) { }
00175 template<class OT, LargeInt OMaxVal, LargeInt OMinVal, class OBoundary>
00176 Float(const Integer<OT,OMaxVal,OMinVal, OBoundary>& other)
00177 : n(crop(value_type(Max*(other.mag())))) { }
00178
00180 void operator= (const LargeFloat& val) { n=value_type(crop(val)); assert(n>=Min&&n<=Max); }
00181
00183 Magnitude mag() const { assert(n>=Min&&n<=Max); return LargeFloat(n)/LargeFloat(Max); }
00184
00186 value_type raw() const { assert(n>=Min&&n<=Max); return n; }
00187 };
00188
00189
00190 template<class T, LargeInt MaxVal, LargeInt MinVal, class Boundary>
00191 const T Float<T,MaxVal,MinVal,Boundary>::Min=MinVal;
00192 template<class T, LargeInt MaxVal, LargeInt MinVal, class Boundary>
00193 const T Float<T,MaxVal,MinVal,Boundary>::Max=MaxVal;
00194
00195
00196 }
00197
00198 #endif