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 #include "bounded.h"
00016
00017
00018 namespace Bounded {
00019
00020
00021
00023 template<class T>
00024 struct Crop { T operator() (T l, T u, T x) { return Generic::crop(l,u,x); } };
00025
00026
00028 template<class T>
00029 struct Wrap { T operator() (T l, T u, T x) { return Generic::wrap(l,u,x); } };
00030
00031
00032
00033
00034
00035
00036 template<class, LargeInt, LargeInt, class> class Integer;
00037 template<class, LargeInt, LargeInt, class> class Float;
00038
00039
00040
00045 #define MAX_UNSIGNED(T) ((sizeof(T)<<8)-1)
00046
00047
00048
00063 template<class T, LargeInt MaxVal=LargeInt(MAX_UNSIGNED(T)),
00064 LargeInt MinVal=0, class Boundary=Crop<LargeInt> >
00065 class Integer {
00066 private:
00067 typedef T value_type;
00068 value_type n;
00069 typedef Integer self;
00070
00071 inline const LargeInt crop(const LargeInt x)
00072 { return Boundary()(Min,Max,x); }
00073
00075 inline value_type set(const LargeInt x)
00076 { return n=value_type(Boundary()(Min,Max,x)); }
00077
00078
00079
00080 public:
00081 static const value_type Min=MinVal;
00082 static const value_type Max=MaxVal;
00084 Integer() : n(set(0)) { }
00085 Integer(value_type val) : n(set(val)) { }
00086 Integer(const self& other)
00087 : n(other.n) { }
00090 template<class OT, LargeInt OMaxVal, LargeInt OMinVal, class OBoundary>
00091 Integer(const Float<OT,OMaxVal,OMinVal,OBoundary>& other)
00092 : n(set(value_type(Max*other.mag()))) { }
00093
00095 void operator= (const LargeInt& val) { set(val); assert(n<=Max); }
00096
00098 self& operator*=(const LargeFloat m) { set(LargeInt(n*m)); return *this; }
00099
00101 self operator+(const self &B) const {
00102 self tmp;
00103 tmp.set(n+B.n);
00104 return tmp;
00105 }
00106
00107
00109 Magnitude mag() const { assert(n<=Max); return LargeFloat(n)/LargeFloat(Max); }
00110
00112 value_type raw() const { assert(n<=Max); return n; }
00113 };
00114
00115
00116
00129 template<class T, LargeInt MaxVal=1, LargeInt MinVal=0, class Boundary=Crop<LargeFloat> >
00130 class Float {
00131 private:
00132 typedef T value_type;
00133 value_type n;
00135 inline const LargeFloat crop(const LargeFloat x)
00136 { return Boundary()(Min,Max,x); }
00137
00138 public:
00139 static const value_type Min;
00140 static const value_type Max;
00142 Float() : n(crop(0)) { }
00143 Float(value_type val) : n(crop(val)) { }
00144 Float(const Float<T,MaxVal,MinVal,Boundary>& other)
00145 : n(other.n) { }
00148 template<class OT, LargeInt OMaxVal, LargeInt OMinVal, class OBoundary>
00149 Float(const Integer<OT,OMaxVal,OMinVal, OBoundary>& other)
00150 : n(crop(value_type(Max*(other.mag())))) { }
00151
00153 void operator= (const LargeFloat& val) { n=value_type(crop(val)); assert(n>=Min&&n<=Max); }
00154
00156 Magnitude mag() const { assert(n>=Min&&n<=Max); return LargeFloat(n)/LargeFloat(Max); }
00157
00159 value_type raw() const { assert(n>=Min&&n<=Max); return n; }
00160 };
00161
00162
00163 template<class T, LargeInt MaxVal, LargeInt MinVal, class Boundary>
00164 const T Float<T,MaxVal,MinVal,Boundary>::Min=MinVal;
00165 template<class T, LargeInt MaxVal, LargeInt MinVal, class Boundary>
00166 const T Float<T,MaxVal,MinVal,Boundary>::Max=MaxVal;
00167
00168
00169 }
00170
00171 #endif