- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/Programmation/Sources/Tensor2/Utils/include/frost_utils_float.h

Go to the documentation of this file.

    00001 // Warning : If you need to use this file, include frost_utils_types.h
    00002 namespace Frost
    00003 {
    00004     /// Base type : float
    00005     /** Frost's base types are made to allow simpler
    00006     *   manipulation of numbers, booleans and strings.
    00007     *   They simplify conversions (mostly to string),
    00008     *   allow easy access to math/string functions and
    00009     *   implements new functions that are not present
    00010     *   in the standard libraries.<br>
    00011     *   <b>Note</b> : Most of Frost's base types are
    00012     *   slower than C++ base types. The difference is
    00013     *   negligible for small operations, but if you need
    00014     *   to do a lot of calculations (matrices, ...) it
    00015     *   can bloat your performances. Use prebuilt types
    00016     *   in this case.
    00017     *   <b>Note</b> : Because the CPU can handle infinite
    00018     *   and nan itself for float types, this class is
    00019     *   more efficient than the others (as fast as the
    00020     *   wrapped POD with compiler optimizations, 5 times
    00021     *   slower in debug mode).
    00022     */
    00023     template <class T>
    00024     class s_float_t
    00025     {
    00026     public :
    00027
    00028         enum Type
    00029         {
    00030             FLOAT,
    00031             FLOAT_INF_PLUS,
    00032             FLOAT_INF_MINUS,
    00033             FLOAT_NAN
    00034         };
    00035
    00036         s_float_t();
    00037
    00038         s_float_t(const T& fValue);
    00039
    00040         explicit s_float_t(const Type& mType);
    00041
    00042         template <class N>
    00043         explicit s_float_t(const s_float_t<N>& fValue)
    00044         {
    00045             fValue_ = static_cast<T>(fValue.Get());
    00046         }
    00047
    00048         template<class N>
    00049         explicit s_float_t(const s_int_t<N>& iValue)
    00050         {
    00051             if (iValue.GetType() == s_int_t<N>::INTEGER_NAN)
    00052             {
    00053                 SetNaN();
    00054             }
    00055             else if (iValue.GetType() == s_int_t<N>::INTEGER_INF_PLUS)
    00056             {
    00057                 SetInfinitePlus();
    00058             }
    00059             else if (iValue.GetType() == s_int_t<N>::INTEGER_INF_MINUS)
    00060             {
    00061                 SetInfiniteMinus();
    00062             }
    00063             else
    00064             {
    00065                 fValue_ = static_cast<T>(iValue.Get());
    00066             }
    00067         }
    00068
    00069         template<class N>
    00070         explicit s_float_t(const s_uint_t<N>& uiValue)
    00071         {
    00072             if (uiValue.GetType() == s_uint_t<N>::INTEGER_NAN)
    00073             {
    00074                 SetNaN();
    00075             }
    00076             else if (uiValue.GetType() == s_uint_t<N>::INTEGER_INF)
    00077             {
    00078                 SetInfinitePlus();
    00079             }
    00080             else
    00081             {
    00082                 fValue_ = static_cast<T>(uiValue.Get());
    00083             }
    00084         }
    00085
    00086         explicit s_float_t(const s_bool& bValue);
    00087
    00088         template<class N>
    00089         explicit s_float_t(const s_str_t<N>& sValue)
    00090         {
    00091             fValue_ = StringToFloat(sValue);
    00092         }
    00093
    00094         /// Adjusts this float's value to be contained into the provided interval.
    00095         /** \param fMin The minimum value
    00096         *   \param fMax The maximum value
    00097         */
    00098         void Clamp(const s_float_t& fMin, const s_float_t& fMax);
    00099
    00100         /// Converts this float to a angle in radian.
    00101         /** \note It is assumed that the previous value was an angle in degree.
    00102         */
    00103         void DegToRad();
    00104
    00105         /// Converts this float to an angle in radian.
    00106         /** \note It is assumed that the previous value was a non dimensionnal angle
    00107         *         (1 = 2*PI rad = 360°).
    00108         */
    00109         s_float_t GetRad() const;
    00110
    00111         /// Converts this float to an angle in degree.
    00112         /** \note It is assumed that the previous value was a non dimensionnal angle
    00113         *         (1 = 2*PI rad = 360°).
    00114         */
    00115         s_float_t GetDeg() const;
    00116
    00117         /// Returns a const reference to the float.
    00118         /** \return A const reference to the float
    00119         */
    00120         inline const T& Get() const { return fValue_; }
    00121
    00122         /// Returns a reference to the float.
    00123         /** \return A reference to the float
    00124         */
    00125         inline T& GetR() { return fValue_; }
    00126
    00127         /// Returns the power of two just above the value (or equal).
    00128         /** \return The associated power of two (2^n) (superior of equal)
    00129         */
    00130         s_uint_t<default_uint> GetNearestPowerOfTwo() const;
    00131
    00132         /// Returns the type of this float.
    00133         /** \return The type of this float (infinite, NaN, ...)
    00134         */
    00135         Type GetType() const;
    00136
    00137         /// Checks if this float is infinite and negative
    00138         /** \return 'true' if this float is infinite and negative
    00139         */
    00140         s_bool IsInfiniteMinus() const;
    00141
    00142         /// Checks if this float is infinite and positive
    00143         /** \return 'true' if this float is infinite and positive
    00144         */
    00145         s_bool IsInfinitePlus() const;
    00146
    00147         /// Checks if this float is contained into the provided range.
    00148         s_bool IsInRange(const s_float_t<T>& fMin, const s_float_t<T>& fMax) const;
    00149
    00150         /// Checks if this float is contained into the provided range, but not equal to either bounds
    00151         s_bool IsInRangeOpen(const s_float_t<T>& fMin, const s_float_t<T>& fMax) const;
    00152
    00153         /// Checks if this float is a Not a Number (NaN)
    00154         /** \return 'true' if this float is NaN
    00155         */
    00156         s_bool IsNaN() const;
    00157
    00158         /// Checks if this float equals zero.
    00159         /** \return 'true' if this float equals zero (precision : EPS)
    00160         */
    00161         s_bool IsNull() const;
    00162
    00163         /// Checks if this float is a valid number.
    00164         /** \return 'true' if this float is not infinite and a number
    00165         */
    00166         s_bool IsValid() const;
    00167
    00168         /// Checks if this float is an infinite number.
    00169         /** \return 'true' if this float is an infinite number
    00170         */
    00171         s_bool IsInfinite() const;
    00172
    00173         /// Elevates this float to a certain power (this^n).
    00174         /** \param fPower The power
    00175         */
    00176         void Pow(const s_float_t& fPower);
    00177
    00178         /// Converts this float to an angle in degree.
    00179         /** \param bNegativeAllowed 'true' if you allow negative return values
    00180         *   \note It is assumed that the previous value was an angle in radian.
    00181         */
    00182         void RadToDeg(const s_bool& bNegativeAllowed = true);
    00183
    00184         /// Sets the value of the float to a random number.
    00185         /** \param fMin The lower bound (minimum)
    00186         *   \param fMax The upper bound (maximum)
    00187         */
    00188         void Randomize(const s_float_t& fMin = 0.0, const s_float_t& fMax = 1.0);
    00189
    00190         /// Rounds the value.
    00191         /** \note If the decimal part is greater than 0.5, the number is rounded up.
    00192         *         Else the number is rounded down.
    00193         */
    00194         void Round();
    00195
    00196         /// Rounds up the value.
    00197         void RoundUp();
    00198
    00199         /// Rounds down the value.
    00200         void RoundDown();
    00201
    00202         /// Sets this float to infinite (negative).
    00203         void SetInfiniteMinus();
    00204
    00205         /// Sets this float to infinite (positive).
    00206         void SetInfinitePlus();
    00207
    00208         /// Set this float to Not a Number state.
    00209         void SetNaN();
    00210
    00211         /// Returns the sign of this float.
    00212         /** \return The sign of this float
    00213         */
    00214         s_float_t GetSign() const;
    00215
    00216         /// Converts this float to an angle in degree.
    00217         /** \param bNegativeAllowed 'true' if you allow negative return values
    00218         *   \note It is assumed that the previous value was a non dimensionnal angle
    00219         *         (1 = 2*PI rad = 360°).
    00220         */
    00221         void ToDeg(const s_bool& bNegativeAllowed);
    00222
    00223         /// Converts this float to an angle in radian.
    00224         /** \note It is assumed that the previous value was a non dimensionnal angle
    00225         *         (1 = 2*PI rad = 360°).
    00226         */
    00227         void ToRad();
    00228
    00229         s_float_t operator - () const;
    00230         s_float_t operator + (const s_float_t& fValue) const;
    00231         s_float_t operator - (const s_float_t& fValue) const;
    00232         s_float_t operator * (const s_float_t& fValue) const;
    00233         s_float_t operator / (const s_float_t& fValue) const;
    00234
    00235         void operator += (const s_float_t& fValue);
    00236         void operator -= (const s_float_t& fValue);
    00237         void operator *= (const s_float_t& fValue);
    00238         void operator /= (const s_float_t& fValue);
    00239
    00240         s_bool operator == (const s_float_t& fValue) const;
    00241         s_bool operator != (const s_float_t& fValue) const;
    00242         s_bool operator < (const s_float_t& fValue) const;
    00243         s_bool operator > (const s_float_t& fValue) const;
    00244         s_bool operator <= (const s_float_t& fValue) const;
    00245         s_bool operator >= (const s_float_t& fValue) const;
    00246
    00247         static const s_float_t    NaN;
    00248         static const s_float_t    INFPLUS;
    00249         static const s_float_t    INFMINUS;
    00250         static const T            EPS;
    00251         static const s_float_t    PI;
    00252         static const default_uint DIGIT;
    00253
    00254         /// Converts a float to an angle in radian.
    00255         /** \note It is assumed that the value was a non dimensionnal angle
    00256         *         (1 = 2*PI rad = 360°).
    00257         */
    00258         static s_float_t ToRad(const s_float_t& fValue);
    00259
    00260         /// Converts this float to an angle in degree.
    00261         /** \note It is assumed that the value was a non dimensionnal angle
    00262         *         (1 = 2*PI rad = 360°).
    00263         */
    00264         static s_float_t ToDeg(const s_float_t& fValue);
    00265
    00266         /// Converts a float to a angle in radian.
    00267         /** \note It is assumed that the value was an angle in degree.
    00268         */
    00269         static s_float_t DegToRad(const s_float_t& fValue);
    00270
    00271         /// Converts a float to a angle in degree.
    00272         /** \note It is assumed that the value was an angle in radian.
    00273         */
    00274         static s_float_t RadToDeg(const s_float_t& fValue);
    00275
    00276         /// Clamps the provided value into the provided interval.
    00277         /** \param fValue The value to clamp
    00278         *   \param fMin   The minimum value
    00279         *   \param fMax   The maximum value
    00280         *   \return The clamped value
    00281         */
    00282         static s_float_t Clamp(const s_float_t& fValue, const s_float_t& fMin, const s_float_t& fMax);
    00283
    00284         /// Returns the lowest value of the two provided ones.
    00285         /** \param fLeft  The first value
    00286         *   \param fRight The second value
    00287         *   \return The lowest value of the two provided ones
    00288         */
    00289         static s_float_t Min(const s_float_t& fLeft, const s_float_t& fRight);
    00290
    00291         /// Returns the highest value of the two provided ones.
    00292         /** \param fLeft  The first value
    00293         *   \param fRight The second value
    00294         *   \return The highest value of the two provided ones
    00295         */
    00296         static s_float_t Max(const s_float_t& fLeft, const s_float_t& fRight);
    00297
    00298         /// Returns a random float in the provided range.
    00299         /** \param fMin The lower bound (minimum)
    00300         *   \param fMax The upper bound (maximum)
    00301         *   \return A random float in the provided range
    00302         */
    00303         static s_float_t Random(const s_float_t& fMin = 0.0, const s_float_t& fMax = 1.0);
    00304
    00305         /// Rounds a float value.
    00306         /** \param fValue The value to round
    00307         *   \note If the decimal part is greater than 0.5, the number is rounded up.
    00308         *         Else the number is rounded down.
    00309         */
    00310         static s_float_t Round(const s_float_t& fValue);
    00311
    00312         /// Rounds a float value up.
    00313         /** \param fValue The value to round
    00314         */
    00315         static s_float_t RoundUp(const s_float_t& fValue);
    00316
    00317         /// Rounds a float value down.
    00318         /** \param fValue The value to round
    00319         */
    00320         static s_float_t RoundDown(const s_float_t& fValue);
    00321
    00322         /// Returns the sign of the provided float.
    00323         /** \return The sign of the provided float
    00324         */
    00325         static s_float_t Sign(const s_float_t& fValue);
    00326
    00327     private :
    00328
    00329         T fValue_;
    00330     };
    00331
    00332     float MakeFloat(const ulong& ul);
    00333
    00334     template <class T>
    00335     s_float_t<T> operator + (const T& fLeft, const s_float_t<T>& fRight);
    00336     template <class T>
    00337     s_float_t<T> operator - (const T& fLeft, const s_float_t<T>& fRight);
    00338     template <class T>
    00339     s_float_t<T> operator * (const T& fLeft, const s_float_t<T>& fRight);
    00340     template <class T>
    00341     s_float_t<T> operator / (const T& fLeft, const s_float_t<T>& fRight);
    00342
    00343     /** \cond NOT_REMOVE_FROM_DOC
    00344     */
    00345     template<> class TypeTraits<float>
    00346     {
    00347     public :
    00348         typedef float            Type;
    00349         typedef float            BaseType;
    00350         typedef s_float_t<float> FrostType;
    00351         typedef float&           RefType;
    00352         typedef const float&     CRefType;
    00353         typedef float*           PointerType;
    00354
    00355         static inline RefType  GetValue(RefType m)  { return m; }
    00356         static inline CRefType GetValue(CRefType m) { return m; }
    00357     };
    00358     template<> class TypeTraits<double>
    00359     {
    00360     public :
    00361         typedef double            Type;
    00362         typedef double            BaseType;
    00363         typedef s_float_t<double> FrostType;
    00364         typedef double&           RefType;
    00365         typedef const double&     CRefType;
    00366         typedef double*           PointerType;
    00367
    00368         static inline RefType  GetValue(RefType m)  { return m; }
    00369         static inline CRefType GetValue(CRefType m) { return m; }
    00370     };
    00371     template<> class TypeTraits<long double>
    00372     {
    00373     public :
    00374         typedef long double            Type;
    00375         typedef long double            BaseType;
    00376         typedef s_float_t<long double> FrostType;
    00377         typedef long double&           RefType;
    00378         typedef const long double&     CRefType;
    00379         typedef long double*           PointerType;
    00380
    00381         static inline RefType  GetValue(RefType m)  { return m; }
    00382         static inline CRefType GetValue(CRefType m) { return m; }
    00383     };
    00384
    00385     template<class T> class TypeTraits< s_float_t<T> >
    00386     {
    00387     public :
    00388         typedef s_float_t<T>        Type;
    00389         typedef T                   BaseType;
    00390         typedef s_float_t<T>        FrostType;
    00391         typedef s_float_t<T>&       RefType;
    00392         typedef const s_float_t<T>& CRefType;
    00393         typedef s_float_t<T>*       PointerType;
    00394
    00395         static inline typename TypeTraits<BaseType>::RefType  GetValue(RefType m)  { return m.GetR(); }
    00396         static inline typename TypeTraits<BaseType>::CRefType GetValue(CRefType m) { return m.Get(); }
    00397     };
    00398     /** \endcond
    00399     */
    00400 }