1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #pragma once19 20 #ifdef MATH_ENABLE_STL_SUPPORT21 #include <iostream>22 #endif23 24 [MATH_BEGIN_NAMESPACE]25 26 27 28 29 30 31 template<typename BaseT, int FracSize>32 class [FixedPoint]33 {34 public:35 enum36 {37 [One] = 1 << FracSize,38 [IntBits] = sizeof(BaseT)*8 - FracSize - 1, 39 [FracBits] = FracSize,40 [MaxVal] = (1 << ([IntBits]))-1, 41 [MaxFrac] = (1 << [FracBits])-1,42 [Epsilon] = 143 };44 45 46 BaseT [value];47 48 [FixedPoint]()49 {50 }51 52 53 [FixedPoint](const BaseT &v)54 :[value](v << [FracBits])55 {56 }57 58 59 [FixedPoint](const BaseT &whole, const BaseT &frac)60 :[value]((whole << [FracBits]) + frac)61 {62 }63 64 65 66 [FixedPoint](const BaseT &whole, const BaseT &nomin, const BaseT &denom)67 :[value]((whole << [FracBits]) + (nomin << [FracBits]) / denom)68 {69 [assert](denom != 0);70 }71 72 operator double() const73 {74 return [value]/(double)[One];75 }76 77 operator float() const78 {79 return [value]/(float)[One];80 }81 82 83 BaseT [Int]() const { return [value] >> [FracBits]; }84 85 BaseT [Frac]() const { return [value] & [MaxFrac]; }86 };87 88 template<typename T, int F, int F2>89 void [Add]([FixedPoint<T, F>] &dst, const [FixedPoint<T, F2>] &src)90 {91 if (F > F2)92 dst.[value] += src.[value] << (F - F2);93 else if (F < F2)94 dst.[value] += src.[value] >> (F2 - F);95 else96 dst.[value] += src.[value];97 }98 99 template<typename T, int F>100 void [Add]([FixedPoint<T, F>] &dst, const T &src)101 {102 dst.[value] += src << FixedPoint<T, F>::FracBits;103 }104 105 template<typename T, int F, int F2>106 void [Sub]([FixedPoint<T, F>] &dst, const [FixedPoint<T, F2>] &src)107 {108 if (F > F2)109 dst.[value] -= src.[value] << (F - F2);110 else if (F < F2)111 dst.[value] -= src.[value] >> (F2 - F);112 else113 dst.[value] -= src.[value];114 }115 116 template<typename T, int F>117 void [Sub]([FixedPoint<T, F>] &dst, const T &src)118 {119 dst.[value] -= src.value << [FixedPoint<T, F>::FracBits];120 }121 122 template<typename T, int F>123 void [Mul]([FixedPoint<T, F>] &dst, const T &src)124 {125 dst.[value] *= src;126 }127 128 129 130 template<typename T, int F, int F2>131 void [MulExtraFast]([FixedPoint<T, F>] &a, const [FixedPoint<T, F2>] &b)132 {133 a.[value] = (a.[value] * b.[value]) >> [FixedPoint<T, F2>::FracBits];134 }135 136 137 138 template<typename T, int F, int F2>139 void [MulFast]([FixedPoint<T, F>] &a, const [FixedPoint<T, F>] &b)140 {141 142 a.[value] = (a.[value] >> (([FixedPoint<T, F2>::FracBits]+1)/2)) * (b.[value] >> ([FixedPoint<T, F2>::FracBits]/2));143 }144 145 146 147 template<typename T, int F>148 void [MulPrecise]([FixedPoint<T, F>] &a, const [FixedPoint<T, F>] &b)149 {150 a.[value] = ((a.[Int]() * b.[Int]()) << [FixedPoint<T, F>::FracBits]) +151 (a.[Int]() * b.[Frac]() + a.[Frac]() * b.[Int]()) +152 ((a.[Frac]() * b.[Frac]()) >> ([FixedPoint<T, F>::FracBits]));153 }154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 template<typename T, int F>197 void [Div]([FixedPoint<T, F>] &a, const T &b)198 {199 a.[value] /= b;200 }201 202 template<typename T, int F, int F2>203 void [DivExtraFast]([FixedPoint<T, F>] &a, const [FixedPoint<T, F2>] &b)204 {205 a.[value] = (a.[value] << [FixedPoint<T, F2>::FracBits]) / b.[value];206 }207 208 template<typename T, int F>209 const [FixedPoint<T, F>] &[operator+=]([FixedPoint<T, F>] &a, const [FixedPoint<T, F>] &b)210 {211 [Add](a, b);212 return a;213 }214 215 template<typename T, int F>216 const [FixedPoint<T, F>] &[operator+=]([FixedPoint<T, F>] &a, const T &b)217 {218 [Add](a, b);219 return a;220 }221 222 template<typename T, int F>223 const [FixedPoint<T, F>] [operator+](const [FixedPoint<T, F>] &a, const [FixedPoint<T, F>] &b)224 {225 [FixedPoint<T, F>] t(a);226 t += b;227 return t;228 }229 230 template<typename T, int F>231 const [FixedPoint<T, F>] [operator+](const [FixedPoint<T, F>] &a, const T &b)232 {233 [FixedPoint<T, F>] t(a);234 t += b;235 return t;236 }237 238 template<typename T, int F>239 const [FixedPoint<T, F>] &[operator-=]([FixedPoint<T, F>] &a, const [FixedPoint<T, F>] &b)240 {241 [Sub](a, b);242 return a;243 }244 245 template<typename T, int F>246 const [FixedPoint<T, F>] [operator-](const [FixedPoint<T, F>] &a, const [FixedPoint<T, F>] &b)247 {248 [FixedPoint<T, F>] t(a);249 t -= b;250 return t;251 }252 253 template<typename T, int F>254 const [FixedPoint<T, F>] &[operator*=]([FixedPoint<T, F>] &a, const [FixedPoint<T, F>] &b)255 {256 [MulPrecise](a, b);257 return a;258 }259 260 template<typename T, int F>261 const [FixedPoint<T, F>] [operator*](const [FixedPoint<T, F>] &a, const [FixedPoint<T, F>] &b)262 {263 [FixedPoint<T, F>] t(a);264 t *= b;265 return t;266 }267 268 template<typename T, int F>269 bool operator<(const FixedPoint<T, F> &a, const T &b)270 {271 return a.[Int]() < b;272 }273 274 template<typename T, int F>275 bool operator<(const FixedPoint<T, F> &a, const [FixedPoint<T, F>] &b)276 {277 return a.[value] < b.value;278 }279 280 template<typename T, int F>281 bool [operator==](const [FixedPoint<T, F>] &a, const T &b)282 {283 return a.[value] == b << FixedPoint<T, F>::FracBits;284 }285 286 template<typename T, int F>287 bool [operator==](const [FixedPoint<T, F>] &a, const [FixedPoint<T, F>] &b)288 {289 return a.[value] == b.[value];290 }291 292 template<typename T, int F>293 bool [operator!=](const [FixedPoint<T, F>] &a, const [FixedPoint<T, F>] &b)294 {295 return !(a == b);296 }297 298 #ifdef MATH_ENABLE_STL_SUPPORT299 template<typename T, int F>300 std::ostream &operator<<(std::ostream &out, const FixedPoint<T, F> &f)301 {302 303 if (f < 0 && f.Frac() != 0)304 out << f.Int()+1 << "." << ([FixedPoint<T, F>::One]-f.[Frac]()) * 10000 / [FixedPoint<T, F>::One];305 else306 out << f.[Int]() << "." << f.Frac() * 10000 / [FixedPoint<T, F>::One];307 return out;308 }309 #endif310 311 [MATH_END_NAMESPACE] Go back to previous page