- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/Programmation/Sources/Tensor2/Utils/src/frost_utils_float_impl.cpp

Go to the documentation of this file.

    00001 #include "frost_utils_types.h"
    00002
    00003 #include <cfloat>
    00004 #include <limits>
    00005 #include <cmath>
    00006
    00007 namespace Frost {
    00008
    00009 template <class T>
    00010 s_float_t<T>::s_float_t()
    00011 {
    00012     fValue_ = 0.0;
    00013 }
    00014
    00015 template <class T>
    00016 s_float_t<T>::s_float_t(const T& fValue)
    00017 {
    00018     fValue_ = fValue;
    00019 }
    00020
    00021 template <class T>
    00022 s_float_t<T>::s_float_t(const Type& mType)
    00023 {
    00024     switch (mType)
    00025     {
    00026         case FLOAT_INF_PLUS  : SetInfinitePlus();
    00027         case FLOAT_INF_MINUS : SetInfiniteMinus();
    00028         case FLOAT_NAN       : SetNaN();
    00029         default : fValue_ = 0.0;
    00030     }
    00031 }
    00032
    00033 template <class T>
    00034 s_float_t<T>::s_float_t(const s_bool& bValue)
    00035 {
    00036     if (bValue)
    00037         fValue_ = 1.0;
    00038     else
    00039         fValue_ = 0.0;
    00040 }
    00041
    00042 template <class T>
    00043 void s_float_t<T>::Clamp(const s_float_t& fMin, const s_float_t& fMax)
    00044 {
    00045     fValue_ = (fValue_ < fMax.fValue_) ? ((fValue_ > fMin.fValue_) ? fValue_ : fMin.fValue_) : fMax.fValue_;
    00046 }
    00047
    00048 template <class T>
    00049 void s_float_t<T>::DegToRad()
    00050 {
    00051     if (IsValid())
    00052     {
    00053         fValue_ *= PI.fValue_/180.0;
    00054     }
    00055 }
    00056
    00057 template <class T>
    00058 s_float_t<T> s_float_t<T>::GetRad() const
    00059 {
    00060     if (IsValid())
    00061     {
    00062         return fValue_*2*PI.fValue_;
    00063     }
    00064     else
    00065         return 0.0;
    00066 }
    00067
    00068 template <class T>
    00069 s_float_t<T> s_float_t<T>::GetDeg() const
    00070 {
    00071     if (IsValid())
    00072     {
    00073         return fValue_*360.0;
    00074     }
    00075     else
    00076         return 0.0;
    00077 }
    00078
    00079 template <class T>
    00080 s_uint_t<default_uint> s_float_t<T>::GetNearestPowerOfTwo() const
    00081 {
    00082     if (IsValid())
    00083     {
    00084         default_uint i = 1;
    00085         while (fValue_ > i)
    00086             i = i << 1;
    00087
    00088         return i;
    00089     }
    00090     else
    00091         return s_uint_t<default_uint>::NaN;
    00092 }
    00093
    00094 template <class T>
    00095 typename s_float_t<T>::Type s_float_t<T>::GetType() const
    00096 {
    00097     if (IsNaN())
    00098         return FLOAT_NAN;
    00099     else
    00100     {
    00101         if (IsValid())
    00102             return FLOAT;
    00103         else
    00104         {
    00105             if (fValue_ < 0.0)
    00106                 return FLOAT_INF_MINUS;
    00107             else
    00108                 return FLOAT_INF_PLUS;
    00109         }
    00110     }
    00111 }
    00112
    00113 template <class T>
    00114 s_bool s_float_t<T>::IsInfiniteMinus() const
    00115 {
    00116     return (IsInfinite() && (fValue_ < 0.0));
    00117 }
    00118
    00119 template <class T>
    00120 s_bool s_float_t<T>::IsInfinitePlus() const
    00121 {
    00122     return (IsInfinite() && (fValue_ > 0.0));
    00123 }
    00124
    00125 template <class T>
    00126 s_bool s_float_t<T>::IsInRange(const s_float_t<T>& fMin, const s_float_t<T>& fMax) const
    00127 {
    00128     return ( (fMin <= (*this)) && ((*this) <= fMax) );
    00129 }
    00130
    00131 template <class T>
    00132 s_bool s_float_t<T>::IsInRangeOpen(const s_float_t<T>& fMin, const s_float_t<T>& fMax) const
    00133 {
    00134     return ( (fMin < (*this)) && ((*this) < fMax) );
    00135 }
    00136
    00137 template <class T>
    00138 s_bool s_float_t<T>::IsNaN() const
    00139 {
    00140     #ifdef MSVC
    00141         return _isnan(fValue_) != 0;
    00142     #else
    00143         return std::isnan(fValue_);
    00144     #endif
    00145 }
    00146
    00147 template <class T>
    00148 s_bool s_float_t<T>::IsNull() const
    00149 {
    00150     return ( IsValid() && (fValue_ < EPS) && (fValue_ > -EPS) );
    00151 }
    00152
    00153 template <class T>
    00154 s_bool s_float_t<T>::IsValid() const
    00155 {
    00156     #ifdef MSVC
    00157         return _finite(fValue_) != 0;
    00158     #else
    00159         return std::isfinite(fValue_);
    00160     #endif
    00161 }
    00162
    00163 template <class T>
    00164 s_bool s_float_t<T>::IsInfinite() const
    00165 {
    00166     #ifdef MSVC
    00167         return (_finite(fValue_) == 0) && (_isnan(fValue_) == 0);
    00168     #else
    00169         return !std::isfinite(fValue_) && !std::isnan(fValue_);
    00170     #endif
    00171 }
    00172
    00173 template <class T>
    00174 void s_float_t<T>::Pow(const s_float_t& fPower)
    00175 {
    00176     if (IsValid() && fPower.IsValid())
    00177     {
    00178         fValue_ = pow(fValue_, fPower.fValue_);
    00179     }
    00180 }
    00181
    00182 template <class T>
    00183 void s_float_t<T>::RadToDeg(const s_bool& bNegativeAllowed)
    00184 {
    00185     if (IsValid())
    00186     {
    00187         fValue_ *= 180.0/PI.fValue_;
    00188         if ( (!bNegativeAllowed) && (fValue_ < 0.0) )
    00189             fValue_ += 360.0;
    00190     }
    00191 }
    00192
    00193 template <class T>
    00194 void s_float_t<T>::Randomize(const s_float_t& fMin, const s_float_t& fMax)
    00195 {
    00196     if (fMin.IsValid() && fMax.IsValid())
    00197     {
    00198         if (fMax < fMin)
    00199             fValue_ = fMin.fValue_;
    00200         else
    00201         {
    00202             T fRange = fMax.fValue_ - fMin.fValue_;
    00203             fValue_ = fRange*(rand()/((T)RAND_MAX)) + fMin.fValue_;
    00204         }
    00205     }
    00206 }
    00207
    00208 template <class T>
    00209 void s_float_t<T>::Round()
    00210 {
    00211     fValue_ = round(fValue_);
    00212 }
    00213
    00214 template <class T>
    00215 void s_float_t<T>::RoundUp()
    00216 {
    00217     fValue_ = ceil(fValue_);
    00218 }
    00219
    00220 template <class T>
    00221 void s_float_t<T>::RoundDown()
    00222 {
    00223     fValue_ = floor(fValue_);
    00224 }
    00225
    00226 template <class T>
    00227 void s_float_t<T>::SetInfiniteMinus()
    00228 {
    00229     fValue_ = INFMINUS.fValue_;
    00230 }
    00231
    00232 template <class T>
    00233 void s_float_t<T>::SetInfinitePlus()
    00234 {
    00235     fValue_ = INFPLUS.fValue_;
    00236 }
    00237
    00238 template <class T>
    00239 void s_float_t<T>::SetNaN()
    00240 {
    00241     fValue_ = NaN.fValue_;
    00242 }
    00243
    00244 template <class T>
    00245 s_float_t<T> s_float_t<T>::GetSign() const
    00246 {
    00247     if (IsValid())
    00248     {
    00249         return (fValue_ < 0.0) ? -1 : 1;
    00250     }
    00251     else
    00252         return s_float_t::NaN;
    00253 }
    00254
    00255 template <class T>
    00256 void s_float_t<T>::ToDeg(const s_bool& bNegativeAllowed)
    00257 {
    00258     if (IsValid())
    00259     {
    00260         fValue_ *= 360.0;
    00261         if ( (!bNegativeAllowed) && (fValue_ < 0.0) )
    00262             fValue_ += 360.0;
    00263     }
    00264 }
    00265
    00266 template <class T>
    00267 void s_float_t<T>::ToRad()
    00268 {
    00269     if (IsValid())
    00270     {
    00271         fValue_ *= 2*PI.fValue_;
    00272     }
    00273 }
    00274
    00275 template <class T>
    00276 s_float_t<T> s_float_t<T>::operator - () const
    00277 {
    00278     return -fValue_;
    00279 }
    00280
    00281 template <class T>
    00282 s_float_t<T> s_float_t<T>::operator + (const s_float_t& fValue) const
    00283 {
    00284     return fValue_ + fValue.fValue_;
    00285 }
    00286
    00287 template <class T>
    00288 s_float_t<T> s_float_t<T>::operator - (const s_float_t& fValue) const
    00289 {
    00290     return fValue_ - fValue.fValue_;
    00291 }
    00292
    00293 template <class T>
    00294 s_float_t<T> s_float_t<T>::operator * (const s_float_t& fValue) const
    00295 {
    00296     return fValue_ * fValue.fValue_;
    00297 }
    00298
    00299 template <class T>
    00300 s_float_t<T> s_float_t<T>::operator / (const s_float_t& fValue) const
    00301 {
    00302     return fValue_ / fValue.fValue_;
    00303 }
    00304
    00305 template <class T>
    00306 void s_float_t<T>::operator += (const s_float_t& fValue)
    00307 {
    00308     fValue_ += fValue.fValue_;
    00309 }
    00310
    00311 template <class T>
    00312 void s_float_t<T>::operator -= (const s_float_t& fValue)
    00313 {
    00314     fValue_ -= fValue.fValue_;
    00315 }
    00316
    00317 template <class T>
    00318 void s_float_t<T>::operator *= (const s_float_t& fValue)
    00319 {
    00320     fValue_ *= fValue.fValue_;
    00321 }
    00322
    00323 template <class T>
    00324 void s_float_t<T>::operator /= (const s_float_t& fValue)
    00325 {
    00326     fValue_ /= fValue.fValue_;
    00327 }
    00328
    00329 template <class T>
    00330 s_bool s_float_t<T>::operator == (const s_float_t& fValue) const
    00331 {
    00332     return (fValue_ == fValue.fValue_);
    00333 }
    00334
    00335 template <class T>
    00336 s_bool s_float_t<T>::operator != (const s_float_t& fValue) const
    00337 {
    00338     return (fValue_ != fValue.fValue_);
    00339 }
    00340
    00341 template <class T>
    00342 s_bool s_float_t<T>::operator < (const s_float_t& fValue) const
    00343 {
    00344     return (fValue_ < fValue.fValue_);
    00345 }
    00346
    00347 template <class T>
    00348 s_bool s_float_t<T>::operator > (const s_float_t& fValue) const
    00349 {
    00350     return (fValue_ > fValue.fValue_);
    00351 }
    00352
    00353 template <class T>
    00354 s_bool s_float_t<T>::operator <= (const s_float_t& fValue) const
    00355 {
    00356     return (fValue_ <= fValue.fValue_);
    00357 }
    00358
    00359 template <class T>
    00360 s_bool s_float_t<T>::operator >= (const s_float_t& fValue) const
    00361 {
    00362     return (fValue_ >= fValue.fValue_);
    00363 }
    00364
    00365 template <class T>
    00366 s_float_t<T> s_float_t<T>::ToRad(const s_float_t& fValue)
    00367 {
    00368     return fValue * 2*PI;
    00369 }
    00370
    00371 template <class T>
    00372 s_float_t<T> s_float_t<T>::ToDeg(const s_float_t& fValue)
    00373 {
    00374     return fValue * 360;
    00375 }
    00376
    00377 template <class T>
    00378 s_float_t<T> s_float_t<T>::DegToRad(const s_float_t& fValue)
    00379 {
    00380     return fValue * PI / 180;
    00381 }
    00382
    00383 template <class T>
    00384 s_float_t<T> s_float_t<T>::RadToDeg(const s_float_t& fValue)
    00385 {
    00386     return fValue * 180 / PI;
    00387 }
    00388
    00389 template <class T>
    00390 s_float_t<T> s_float_t<T>::Clamp(const s_float_t& fValue, const s_float_t& fMin, const s_float_t& fMax)
    00391 {
    00392     return (fValue.fValue_ < fMax.fValue_) ? ((fValue.fValue_ > fMin.fValue_) ? fValue.fValue_ : fMin.fValue_) : fMax.fValue_;
    00393 }
    00394
    00395 template <class T>
    00396 s_float_t<T> s_float_t<T>::Min(const s_float_t& fLeft, const s_float_t& fRight)
    00397 {
    00398     return (fLeft >= fRight) ? fRight : fLeft;
    00399 }
    00400
    00401 template <class T>
    00402 s_float_t<T> s_float_t<T>::Max(const s_float_t& fLeft, const s_float_t& fRight)
    00403 {
    00404     return (fLeft <= fRight) ? fRight : fLeft;
    00405 }
    00406
    00407 template <class T>
    00408 s_float_t<T> s_float_t<T>::Random(const s_float_t& fMin, const s_float_t& fMax)
    00409 {
    00410     if (fMin.IsValid() && fMax.IsValid())
    00411     {
    00412         if (fMax.fValue_ < fMin.fValue_)
    00413         {
    00414             return fMin;
    00415         }
    00416         else
    00417         {
    00418             T fRange = fMax.fValue_ - fMin.fValue_;
    00419             return fRange*(rand()/((T)RAND_MAX)) + fMin.fValue_;
    00420         }
    00421     }
    00422     else
    00423         return s_float_t::NaN;
    00424 }
    00425
    00426 template <class T>
    00427 s_float_t<T> s_float_t<T>::Round(const s_float_t& fValue)
    00428 {
    00429     return round(fValue.fValue_);
    00430 }
    00431
    00432 template <class T>
    00433 s_float_t<T> s_float_t<T>::RoundUp(const s_float_t& fValue)
    00434 {
    00435     return ceil(fValue.fValue_);
    00436 }
    00437
    00438 template <class T>
    00439 s_float_t<T> s_float_t<T>::RoundDown(const s_float_t& fValue)
    00440 {
    00441     return floor(fValue.fValue_);
    00442 }
    00443
    00444 template <class T>
    00445 s_float_t<T> s_float_t<T>::Sign(const s_float_t& fValue)
    00446 {
    00447     if (fValue.IsValid())
    00448     {
    00449         return (fValue.fValue_ < 0.0) ? -1 : 1;
    00450     }
    00451     else
    00452         return s_float_t::NaN;
    00453 }
    00454
    00455 template <class T>
    00456 const s_float_t<T> s_float_t<T>::NaN      = MakeFloat(0xFFC00000);
    00457 template <class T>
    00458 const s_float_t<T> s_float_t<T>::INFPLUS  = MakeFloat(0x7F800000);
    00459 template <class T>
    00460 const s_float_t<T> s_float_t<T>::INFMINUS = MakeFloat(0xFF800000);
    00461 template <class T>
    00462 const T s_float_t<T>::EPS = 0.0;
    00463 template <class T>
    00464 const s_float_t<T> s_float_t<T>::PI = 3.1415;
    00465 template <class T>
    00466 const default_uint s_float_t<T>::DIGIT = 1;
    00467
    00468 template <class T>
    00469 s_float_t<T> operator + (const T& fLeft, const s_float_t<T>& fRight)
    00470 {
    00471     return s_float_t<T>(fLeft) + fRight;
    00472 }
    00473
    00474 template <class T>
    00475 s_float_t<T> operator - (const T& fLeft, const s_float_t<T>& fRight)
    00476 {
    00477     return s_float_t<T>(fLeft) - fRight;
    00478 }
    00479
    00480 template <class T>
    00481 s_float_t<T> operator * (const T& fLeft, const s_float_t<T>& fRight)
    00482 {
    00483     return s_float_t<T>(fLeft) * fRight;
    00484 }
    00485
    00486 template <class T>
    00487 s_float_t<T> operator / (const T& fLeft, const s_float_t<T>& fRight)
    00488 {
    00489     return s_float_t<T>(fLeft) / fRight;
    00490 }
    00491
    00492 typedef s_float_t<float>       s_float;
    00493 typedef s_float_t<double>      s_double;
    00494 typedef s_float_t<long double> s_ldouble;
    00495
    00496 template<> const float s_float::EPS  = std::numeric_limits<float>::epsilon();
    00497 template<> const s_float s_float::PI = 3.141592f;
    00498 template<> const default_uint s_float::DIGIT = std::numeric_limits<float>::digits10;
    00499
    00500 template<> const double s_double::EPS  = std::numeric_limits<double>::epsilon();
    00501 template<> const s_double s_double::PI = 3.141592653589793;
    00502 template<> const default_uint s_double::DIGIT  = std::numeric_limits<double>::digits10;
    00503
    00504 template<> const long double s_ldouble::EPS = std::numeric_limits<long double>::epsilon();
    00505 template<> const s_ldouble s_ldouble::PI    = 3.141592653589793238;
    00506 template<> const default_uint s_ldouble::DIGIT      = std::numeric_limits<long double>::digits10;
    00507
    00508 template class s_float_t<float>;
    00509 template class s_float_t<double>;
    00510 template class s_float_t<long double>;
    00511
    00512
    00513 template s_float_t<float> operator + (const float& fLeft, const s_float& fRight);
    00514 template s_float_t<float> operator - (const float& fLeft, const s_float& fRight);
    00515 template s_float_t<float> operator * (const float& fLeft, const s_float& fRight);
    00516 template s_float_t<float> operator / (const float& fLeft, const s_float& fRight);
    00517
    00518 template s_float_t<double> operator + (const double& fLeft, const s_double& fRight);
    00519 template s_float_t<double> operator - (const double& fLeft, const s_double& fRight);
    00520 template s_float_t<double> operator * (const double& fLeft, const s_double& fRight);
    00521 template s_float_t<double> operator / (const double& fLeft, const s_double& fRight);
    00522
    00523 template s_float_t<long double> operator + (const long double& fLeft, const s_ldouble& fRight);
    00524 template s_float_t<long double> operator - (const long double& fLeft, const s_ldouble& fRight);
    00525 template s_float_t<long double> operator * (const long double& fLeft, const s_ldouble& fRight);
    00526 template s_float_t<long double> operator / (const long double& fLeft, const s_ldouble& fRight);
    00527
    00528 }