00001
00025
00026
00027 #ifndef __ETL__FIXED_H
00028 #define __ETL__FIXED_H
00029
00030
00031
00032 #include <cmath>
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef ETL_FIXED_TYPE
00041 # define ETL_FIXED_TYPE int
00042 #endif
00043
00044 #ifndef ETL_FIXED_BITS
00045 #define ETL_FIXED_BITS 12
00046 #endif
00047
00048 #ifndef ETL_FIXED_EPSILON
00049 #define ETL_FIXED_EPSILON _EPSILON()
00050 #endif
00051
00052 #ifdef __GNUC___
00053 #define ETL_ATTRIB_CONST __attribute__ ((const))
00054 #define ETL_ATTRIB_PURE __attribute__ ((pure))
00055 #define ETL_ATTRIB_INLINE __attribute__ ((always_inline))
00056 #else
00057 #define ETL_ATTRIB_CONST
00058 #define ETL_ATTRIB_PURE
00059 #define ETL_ATTRIB_INLINE
00060 #endif
00061
00062
00063
00064 _ETL_BEGIN_NAMESPACE
00065
00066
00067 template<typename T, unsigned int FIXED_BITS> class fixed_base;
00068
00069
00070 _ETL_END_NAMESPACE
00071
00072 _STD_BEGIN_NAMESPACE
00073 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> abs(const _ETL::fixed_base<T,FIXED_BITS>&);
00074 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> cos(const _ETL::fixed_base<T,FIXED_BITS>&);
00075 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> cosh(const _ETL::fixed_base<T,FIXED_BITS>&);
00076 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> exp(const _ETL::fixed_base<T,FIXED_BITS>&);
00077 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> log(const _ETL::fixed_base<T,FIXED_BITS>&);
00078 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> log10(const _ETL::fixed_base<T,FIXED_BITS>&);
00079 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&, int);
00080 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&, const T&);
00081 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&,
00082 const _ETL::fixed_base<T,FIXED_BITS>&);
00083 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> pow(const _ETL::fixed_base<T,FIXED_BITS>&, const _ETL::fixed_base<T,FIXED_BITS>&);
00084 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sin(const _ETL::fixed_base<T,FIXED_BITS>&);
00085 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sinh(const _ETL::fixed_base<T,FIXED_BITS>&);
00086 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> sqrt(const _ETL::fixed_base<T,FIXED_BITS>&);
00087 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> tan(const _ETL::fixed_base<T,FIXED_BITS>&);
00088 template<typename T, unsigned int FIXED_BITS> _ETL::fixed_base<T,FIXED_BITS> tanh(const _ETL::fixed_base<T,FIXED_BITS>&);
00089 _STD_END_NAMESPACE
00090 _ETL_BEGIN_NAMESPACE
00091
00098 template <class T,unsigned int FIXED_BITS>
00099 class fixed_base
00100 {
00101 public:
00102 typedef T value_type;
00103 private:
00104 T _data;
00105
00106 typedef fixed_base<T,FIXED_BITS> _fixed;
00107 typedef fixed_base<T,FIXED_BITS> self_type;
00108
00109 inline static bool _TYPE_SMALLER_THAN_INT() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
00110 inline static bool _USING_ALL_BITS() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
00111 inline static value_type _ONE() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
00112 inline static value_type _F_MASK() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
00113 inline static float _EPSILON() ETL_ATTRIB_CONST ETL_ATTRIB_INLINE;
00114
00115 class raw { };
00116 public:
00117 fixed_base()ETL_ATTRIB_INLINE;
00118 fixed_base(const float &f)ETL_ATTRIB_INLINE;
00119 fixed_base(const double &f)ETL_ATTRIB_INLINE;
00120 fixed_base(const long double &f)ETL_ATTRIB_INLINE;
00121 fixed_base(const int &i)ETL_ATTRIB_INLINE;
00122 fixed_base(const int &n,const int &d)ETL_ATTRIB_INLINE;
00123 fixed_base(const _fixed &x)ETL_ATTRIB_INLINE;
00124 fixed_base(value_type x,raw)ETL_ATTRIB_INLINE;
00125
00126 T &data() ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;
00127 const T &data()const ETL_ATTRIB_PURE ETL_ATTRIB_INLINE;
00128
00129 const _fixed& operator+=(const _fixed &rhs) ETL_ATTRIB_INLINE;
00130 const _fixed& operator-=(const _fixed &rhs) ETL_ATTRIB_INLINE;
00131 template<typename U> const _fixed& operator*=(const U &rhs) ETL_ATTRIB_INLINE;
00132 template<typename U> const _fixed& operator/=(const U &rhs) ETL_ATTRIB_INLINE;
00133 const _fixed& operator*=(const _fixed &rhs) ETL_ATTRIB_INLINE;
00134 const _fixed& operator/=(const _fixed &rhs) ETL_ATTRIB_INLINE;
00135 const _fixed& operator*=(const int &rhs) ETL_ATTRIB_INLINE;
00136 const _fixed& operator/=(const int &rhs) ETL_ATTRIB_INLINE;
00137
00138
00139 template<typename U> _fixed operator+(const U &rhs)const ETL_ATTRIB_INLINE;
00140 template<typename U> _fixed operator-(const U &rhs)const ETL_ATTRIB_INLINE;
00141 template<typename U> _fixed operator*(const U &rhs)const ETL_ATTRIB_INLINE;
00142 template<typename U> _fixed operator/(const U &rhs)const ETL_ATTRIB_INLINE;
00143 _fixed operator+(const _fixed &rhs)const ETL_ATTRIB_INLINE;
00144 _fixed operator-(const _fixed &rhs)const ETL_ATTRIB_INLINE;
00145 _fixed operator*(const _fixed &rhs)const ETL_ATTRIB_INLINE;
00146 _fixed operator/(const _fixed &rhs)const ETL_ATTRIB_INLINE;
00147 _fixed operator*(const int &rhs)const ETL_ATTRIB_INLINE;
00148 _fixed operator/(const int &rhs)const ETL_ATTRIB_INLINE;
00149 _fixed operator*(const float &rhs)const ETL_ATTRIB_INLINE;
00150 _fixed operator*(const double &rhs)const ETL_ATTRIB_INLINE;
00151
00152
00153 _fixed operator-()const ETL_ATTRIB_INLINE;
00154
00155
00156 inline operator float()const ETL_ATTRIB_INLINE;
00157 inline operator double()const ETL_ATTRIB_INLINE;
00158 inline operator long double()const ETL_ATTRIB_INLINE;
00159 inline operator int()const ETL_ATTRIB_INLINE;
00160 inline operator bool()const ETL_ATTRIB_INLINE;
00161
00162 _fixed floor()const;
00163 _fixed ceil()const;
00164 _fixed round()const;
00165
00166 bool operator==(const _fixed &rhs)const { return data()==rhs.data(); }
00167 bool operator!=(const _fixed &rhs)const { return data()!=rhs.data(); }
00168 bool operator<(const _fixed &rhs)const { return data()<rhs.data(); }
00169 bool operator>(const _fixed &rhs)const { return data()>rhs.data(); }
00170 bool operator<=(const _fixed &rhs)const { return data()<=rhs.data(); }
00171 bool operator>=(const _fixed &rhs)const { return data()>=rhs.data(); }
00172 };
00173
00174
00175 template <class T,unsigned int FIXED_BITS>
00176 fixed_base<T,FIXED_BITS>::fixed_base()
00177 {}
00178
00179 template <class T,unsigned int FIXED_BITS>
00180 fixed_base<T,FIXED_BITS>::fixed_base(const _fixed &x):_data(x._data)
00181 {}
00182
00183 template <class T,unsigned int FIXED_BITS>
00184 fixed_base<T,FIXED_BITS>::fixed_base(const float &f):_data(static_cast<value_type>(f*_ONE()
00185 #ifdef ROUND_TO_NEAREST_INTEGER
00186 +0.5f
00187 #endif
00188 )) {}
00189
00190 template <class T,unsigned int FIXED_BITS>
00191 fixed_base<T,FIXED_BITS>::fixed_base(const double &f):_data(static_cast<value_type>(f*_ONE()
00192 #ifdef ROUND_TO_NEAREST_INTEGER
00193 +0.5
00194 #endif
00195 )) {}
00196
00197 template <class T,unsigned int FIXED_BITS>
00198 fixed_base<T,FIXED_BITS>::fixed_base(const long double &f):_data(static_cast<value_type>(f*_ONE()
00199 #ifdef ROUND_TO_NEAREST_INTEGER
00200 +0.5
00201 #endif
00202 )) {}
00203
00204 template <class T,unsigned int FIXED_BITS>
00205 fixed_base<T,FIXED_BITS>::fixed_base(const int &i):_data(i<<FIXED_BITS)
00206 {}
00207
00208 template <class T,unsigned int FIXED_BITS>
00209 fixed_base<T,FIXED_BITS>::fixed_base(value_type x,raw):_data(x) { }
00210
00211 template <class T,unsigned int FIXED_BITS>
00212 fixed_base<T,FIXED_BITS>::fixed_base(const int &n,const int &d):_data((n<<FIXED_BITS)/d) { }
00213
00214
00215
00216 template <class T,unsigned int FIXED_BITS> inline bool
00217 fixed_base<T,FIXED_BITS>::_TYPE_SMALLER_THAN_INT()
00218 {
00219 return sizeof(T)<sizeof(int);
00220 }
00221
00222 template <class T,unsigned int FIXED_BITS> inline bool
00223 fixed_base<T,FIXED_BITS>::_USING_ALL_BITS()
00224 {
00225 return sizeof(T)*8==FIXED_BITS;
00226 }
00227
00228 template <class T,unsigned int FIXED_BITS> inline T
00229 fixed_base<T,FIXED_BITS>::_ONE()
00230 {
00231 return static_cast<T>((_USING_ALL_BITS()?~T(0):1<<FIXED_BITS));
00232 }
00233
00234 template <class T,unsigned int FIXED_BITS> inline T
00235 fixed_base<T,FIXED_BITS>::_F_MASK()
00236 {
00237 return static_cast<T>(_USING_ALL_BITS()?~T(0):_ONE()-1);
00238 }
00239
00240 template <class T,unsigned int FIXED_BITS> inline float
00241 fixed_base<T,FIXED_BITS>::_EPSILON()
00242 {
00243 return 1.0f/((float)_ONE()*2);
00244 }
00245
00246
00247 template <class T,unsigned int FIXED_BITS>T &
00248 fixed_base<T,FIXED_BITS>::data()
00249 {
00250 return _data;
00251 }
00252
00253 template <class T,unsigned int FIXED_BITS>const T &
00254 fixed_base<T,FIXED_BITS>::data()const
00255 {
00256 return _data;
00257 }
00258
00260 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
00261 fixed_base<T,FIXED_BITS>::operator+=(const fixed_base<T,FIXED_BITS> &rhs)
00262 {
00263 _data+=rhs._data;
00264 return *this;
00265 }
00266
00268 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
00269 fixed_base<T,FIXED_BITS>::operator-=(const fixed_base<T,FIXED_BITS> &rhs)
00270 {
00271 _data-=rhs._data;
00272 return *this;
00273 }
00274
00276 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
00277 fixed_base<T,FIXED_BITS>::operator*=(const fixed_base<T,FIXED_BITS> &rhs)
00278 {
00279 if(_TYPE_SMALLER_THAN_INT())
00280 _data=static_cast<T>((int)_data*(int)rhs._data>>FIXED_BITS);
00281 else
00282 {
00283 _data*=rhs._data;
00284 _data>>=FIXED_BITS;
00285 }
00286
00287 return *this;
00288 }
00289
00291 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
00292 fixed_base<T,FIXED_BITS>::operator/=(const fixed_base<T,FIXED_BITS> &rhs)
00293 {
00294 if(_TYPE_SMALLER_THAN_INT())
00295 _data=static_cast<T>((int)_data/(int)rhs._data<<FIXED_BITS);
00296 else
00297 {
00298 _data/=rhs._data;
00299 _data<<=FIXED_BITS;
00300 }
00301 return *this;
00302 }
00303
00304 template <class T,unsigned int FIXED_BITS> template<typename U> const fixed_base<T,FIXED_BITS> &
00305 fixed_base<T,FIXED_BITS>::operator*=(const U &rhs)
00306 {
00307 return operator*=(fixed_base<T,FIXED_BITS>(rhs));
00308 }
00309
00310 template <class T,unsigned int FIXED_BITS> template<typename U> const fixed_base<T,FIXED_BITS> &
00311 fixed_base<T,FIXED_BITS>::operator/=(const U &rhs)
00312 {
00313 return operator/=(fixed_base<T,FIXED_BITS>(rhs));
00314 }
00315
00317 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
00318 fixed_base<T,FIXED_BITS>::operator*=(const int &rhs)
00319 {
00320 _data*=rhs; return *this;
00321 }
00322
00324 template <class T,unsigned int FIXED_BITS>const fixed_base<T,FIXED_BITS> &
00325 fixed_base<T,FIXED_BITS>::operator/=(const int &rhs)
00326 {
00327 _data/=rhs; return *this;
00328 }
00329
00330
00331
00332
00333
00334
00335
00337 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00338 fixed_base<T,FIXED_BITS>::operator+(const fixed_base<T,FIXED_BITS> &rhs)const
00339 {
00340 _fixed ret;
00341 ret._data=_data+rhs._data;
00342 return ret;
00343 }
00344
00346 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00347 fixed_base<T,FIXED_BITS>::operator-(const fixed_base<T,FIXED_BITS> &rhs)const
00348 {
00349 _fixed ret;
00350 ret._data=_data-rhs._data;
00351 return ret;
00352 }
00353
00355 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00356 fixed_base<T,FIXED_BITS>::operator*(const fixed_base<T,FIXED_BITS> &rhs)const
00357 {
00358 _fixed ret;
00359 ret._data=((_data*rhs._data)>>FIXED_BITS);
00360 return ret;
00361
00362 }
00363
00365 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00366 fixed_base<T,FIXED_BITS>::operator/(const fixed_base<T,FIXED_BITS> &rhs)const
00367 {
00368 _fixed ret;
00369 ret._data=((_data/rhs._data)<<FIXED_BITS);
00370 return ret;
00371
00372 }
00373
00375 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
00376 fixed_base<T,FIXED_BITS>::operator+(const U &rhs) const
00377 {
00378 return operator+(fixed_base<T,FIXED_BITS>(rhs));
00379 }
00380
00382 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
00383 fixed_base<T,FIXED_BITS>::operator-(const U &rhs) const
00384 {
00385 return operator-(fixed_base<T,FIXED_BITS>(rhs));
00386 }
00387
00389 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
00390 fixed_base<T,FIXED_BITS>::operator*(const U &rhs) const
00391 {
00392 return operator*(fixed_base<T,FIXED_BITS>(rhs));
00393 }
00394
00396 template <class T,unsigned int FIXED_BITS> template<typename U> fixed_base<T,FIXED_BITS>
00397 fixed_base<T,FIXED_BITS>::operator/(const U &rhs) const
00398 {
00399 return operator/(fixed_base<T,FIXED_BITS>(rhs));
00400 }
00401
00403 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00404 fixed_base<T,FIXED_BITS>::operator*(const int &rhs)const
00405 {
00406 _fixed ret;
00407 ret._data=_data*rhs;
00408 return ret;
00409
00410 }
00411
00413 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00414 fixed_base<T,FIXED_BITS>::operator*(const float &rhs)const
00415 {
00416 return (*this)*_fixed(rhs);
00417 }
00418
00420 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00421 fixed_base<T,FIXED_BITS>::operator*(const double &rhs)const
00422 {
00423 return (*this)*_fixed(rhs);
00424 }
00425
00426
00428 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00429 fixed_base<T,FIXED_BITS>::operator/(const int &rhs)const
00430 {
00431 _fixed ret;
00432 ret._data=_data/rhs;
00433 return ret;
00434
00435 }
00436
00438 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00439 operator*(const float& lhs, const fixed_base<T,FIXED_BITS> &rhs)
00440 {
00441 return rhs*lhs;
00442 }
00443
00445 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00446 operator*(const double& lhs, const fixed_base<T,FIXED_BITS> &rhs)
00447 {
00448 return rhs*lhs;
00449 }
00450
00451
00452
00453
00454
00455
00456
00457 template <class T,unsigned int FIXED_BITS>fixed_base<T,FIXED_BITS>
00458 fixed_base<T,FIXED_BITS>::operator-()const
00459 {
00460 _fixed ret; ret._data=-_data; return ret;
00461 }
00462
00463
00464 template <class T,unsigned int FIXED_BITS>
00465 fixed_base<T,FIXED_BITS>::operator float()const
00466 {
00467 return static_cast<float>(_data)/static_cast<float>(_ONE());
00468 }
00469
00470 template <class T,unsigned int FIXED_BITS>
00471 fixed_base<T,FIXED_BITS>::operator double()const
00472 {
00473 return static_cast<double>(_data)/static_cast<double>(_ONE());
00474 }
00475
00476 template <class T,unsigned int FIXED_BITS>
00477 fixed_base<T,FIXED_BITS>::operator long double()const
00478 {
00479 return static_cast<long double>(_data)/static_cast<long double>(_ONE());
00480 }
00481
00482 template <class T,unsigned int FIXED_BITS>
00483 fixed_base<T,FIXED_BITS>::operator int()const
00484 {
00485 return static_cast<int>(_data>>FIXED_BITS);
00486 }
00487
00488 template <class T,unsigned int FIXED_BITS>
00489 fixed_base<T,FIXED_BITS>::operator bool()const
00490 {
00491 return static_cast<bool>(_data);
00492 }
00493
00494
00495 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
00496 fixed_base<T,FIXED_BITS>::floor()const
00497 {
00498 _fixed ret(*this);
00499 ret._data&=~_F_MASK();
00500 return ret;
00501 }
00502
00503 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
00504 fixed_base<T,FIXED_BITS>::ceil()const
00505 {
00506 _fixed ret(*this);
00507 if(ret._data&_F_MASK())
00508 ret._data=(ret._data&~_F_MASK()) + _ONE();
00509 else
00510 ret._data&=~_F_MASK();
00511 return ret;
00512 }
00513
00514 template <class T,unsigned int FIXED_BITS> fixed_base<T,FIXED_BITS>
00515 fixed_base<T,FIXED_BITS>::round()const
00516 {
00517 _fixed ret(*this);
00518 ret._data+=_ONE()>>1;
00519 ret._data&=~_F_MASK();
00520 return ret;
00521 }
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548 typedef fixed_base<ETL_FIXED_TYPE,ETL_FIXED_BITS> fixed;
00549
00550 _ETL_END_NAMESPACE
00551
00552 _STD_BEGIN_NAMESPACE
00553
00554 template <class T,unsigned int FIXED_BITS>
00555 inline _ETL::fixed_base<T,FIXED_BITS>
00556 ceil(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
00557 { return rhs.ceil(); }
00558
00559 template <class T,unsigned int FIXED_BITS>
00560 _ETL::fixed_base<T,FIXED_BITS>
00561 floor(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
00562 { return rhs.floor(); }
00563
00564 template <class T,unsigned int FIXED_BITS>
00565 _ETL::fixed_base<T,FIXED_BITS>
00566 round(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
00567 { return rhs.round(); }
00568
00569 template <class T,unsigned int FIXED_BITS>
00570 _ETL::fixed_base<T,FIXED_BITS>
00571 abs(const _ETL::fixed_base<T,FIXED_BITS> &rhs)
00572 { return rhs<_ETL::fixed_base<T,FIXED_BITS>(0)?-rhs:rhs; }
00573
00574 _STD_END_NAMESPACE
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603 #if defined(__GNUC__) && __GNUC__ == 3
00604 template <class T,unsigned int FIXED_BITS, typename U> U
00605 operator*(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
00606 { return a*static_cast<double>(b); }
00607
00608 template <class T,unsigned int FIXED_BITS, typename U> U
00609 operator/(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
00610 { return a/static_cast<double>(b); }
00611
00612 template <class T,unsigned int FIXED_BITS, typename U> U
00613 operator+(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
00614 { return a+static_cast<double>(b); }
00615
00616 template <class T,unsigned int FIXED_BITS, typename U> U
00617 operator-(const U &a,const _ETL::fixed_base<T,FIXED_BITS> &b)
00618 { return a-static_cast<double>(b); }
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638 #endif
00639
00640
00641
00642 #endif