mi32/math.h

Go to the documentation of this file.
00001 /**
00002  * \file math.h <mi32/math.h>
00003  * \brief Math functions and prototypes, also includes standard C math hdr.
00004  *
00005  * \if NODOC
00006  * $Id: math.h_v 1.4 2006/07/27 14:53:10 scowan Exp $
00007  *
00008  * $Log: math.h_v $
00009  * Revision 1.4  2006/07/27 14:53:10  scowan
00010  * Include cmath.
00011  *
00012  * Revision 1.3  2006/03/10 15:48:12  mju
00013  * Not allowed asm on win64.
00014  *
00015  * Revision 1.2  2005/09/08 21:25:03  mju
00016  * Don't declare legacy round macro if no_deprecated.
00017  *
00018  * Revision 1.1  2005/07/15 16:24:42  mju
00019  * Initial revision
00020  *
00021  * \endif
00022 **/
00023 
00024 #ifndef  INC_MI32_MATH_H
00025 #define  INC_MI32_MATH_H
00026 
00027 #ifndef  INC_MI32_STDDEFNS_H
00028 #include <mi32/stddefns.h>
00029 #endif
00030 
00031 #ifndef  INC_MATH_H
00032 #include <math.h>
00033 #define  INC_MATH_H
00034 #endif
00035 
00036 #ifndef  INC_CMATH
00037 #include <cmath>     // Definitions for std::abs() for floating point types.
00038 #define  INC_CMATH
00039 #endif
00040 
00041 #ifdef MISYSTEMDLL
00042    #define LIBEXPORT MI_DLLEXPORT
00043 #else
00044    #define LIBEXPORT MI_DLLIMPORT
00045 #endif
00046 
00047 
00048 //!\addtogroup math Math Functions
00049 //!@{
00050 
00051 #if defined(__cplusplus)
00052 extern "C" {
00053 #endif
00054 
00055 #ifndef GENERATING_DOXYGEN_OUTPUT
00056 
00057 #if defined(WIN32)
00058    #if __STDC__ && _MSC_VER >= 1200
00059    #define hypot     _hypot
00060    #endif
00061 
00062 #elif !defined(LINUX)
00063    double hypot (double, double);         // Define this for everywhere else except Win32.  In Win32 it is a DLL import
00064 #endif
00065 
00066 #endif   // GENERATING_DOXYGEN_OUTPUT
00067 
00068 //! Returns the IEEE representation of Not A Number.
00069 LIBEXPORT double IEEE_NaN (void);
00070 
00071 //! Returns the IEEE representation of Infinity.
00072 LIBEXPORT double IEEE_Infinity (void);
00073 
00074 #if defined(__cplusplus)
00075 }
00076 #endif
00077 
00078 #if defined(WIN32) && defined(__cplusplus) && !defined(WIN64)
00079 
00080 // On Intel, avoid the _ftol() call implied by the cast to integer.
00081 // ftol() is slow because of the way it casts.  It first has to switch
00082 // the conversion mode of the processor from round to truncate, which
00083 // cuases all pipelines to stall.  Then it converts the number and switches
00084 // back to rounding mode.  That's a lot of work to truncate a number when
00085 // the default would have been to do What We Wanted (W3)
00086 // Accounts for Intel rounding .5 values to nearest -even- integer, corrects for up to +/- 1000000
00087 
00088 //! Fast round of value to nearest integer, with X.5 values rounded up.
00089 //! This function is approximately 3X faster than using static_cast<INT32>(x+.5) on Intel.
00090 //! Accuracy limitations:
00091 //! Values in the range from -1000000 to +1000000 at exactly .5 will be handled correctly.
00092 //! Values outside that range may not always be rounded up.  In addition, values in the
00093 //! range of -1000 to 1000 which are within 1E-10 of .5 may not be correctly rounded down.
00094 //! The FAST_... functions should not be used if exact accuracy is required.
00095 inline INT32 FAST_ROUND (double x) {
00096    static const double d = 1E-10;
00097    INT32 result;
00098    __asm fld x
00099    __asm fadd d
00100    __asm fistp result
00101    return result;
00102    }
00103 
00104 //! Fast return of smallest integer greater than or equal to specified value.
00105 //! This function is at least 5X faster than using static_cast<INT32>(ceil(x)) on Intel.
00106 //! Accuracy limitations:
00107 //! Values in the range from -1000000 to +1000000 at exactly .0 will be handled correctly.
00108 //! Values outside that range may not always be correct.  In addition, values in the
00109 //! range of -1000 to 1000 which are within 1E-10 of .0 may not be correctly rounded.
00110 //! The FAST_... functions should not be used if exact accuracy is required.
00111 inline INT32 FAST_CEIL (double x) {
00112    static const double d = .4999999999;
00113    INT32 result;
00114    __asm fld x
00115    __asm fadd d
00116    __asm fistp result
00117    return result;
00118    }
00119 
00120 //! Fast return of largest integer less than or equal to specified value.
00121 //! This function is at least 5X faster than using static_cast<INT32>(floor(x)) on Intel.
00122 //! Accuracy limitations:
00123 //! Values in the range from -1000000 to +1000000 at exactly .0 will be handled correctly.
00124 //! Values outside that range may not always be correct.  In addition, values in the
00125 //! range of -1000 to 1000 which are within 1E-10 of .0 may not be correctly rounded.
00126 //! The FAST_... functions should not be used if exact accuracy is required.
00127 inline INT32 FAST_FLOOR (double x) {
00128    static const double d = -.4999999999;
00129    INT32 result;
00130    __asm fld x
00131    __asm fadd d
00132    __asm fistp result
00133    return result;
00134    }
00135 
00136 //! Fast return of largest integer less than or equal to specified value.
00137 //! This function is at approximately 3X faster than using static_cast<INT32>(x) on Intel.
00138 //! If values are known to always be positive (or negative) it will be faster to
00139 //! use the FAST_FLOOR (or FAST_CEIL) function as appropriate.
00140 //! Accuracy limitations:
00141 //! Values in the range from -1000000 to +1000000 at exactly .0 will be handled correctly.
00142 //! Values outside that range may not always be correct.  In addition, values in the
00143 //! range of -1000 to 1000 which are within 1E-10 of .0 may not be correctly rounded.
00144 //! The FAST_... functions should not be used if exact accuracy is required.
00145 inline INT32 FAST_TRUNCATE (double x) {
00146    static const double d = .4999999999;
00147    INT32 result;
00148    if (x < 0) {
00149       __asm fld x
00150       __asm fadd d
00151       __asm fistp result
00152       }
00153    else {
00154       __asm fld x
00155       __asm fsub d
00156       __asm fistp result
00157       }
00158    return result;
00159    }
00160 
00161 
00162 #else
00163 
00164 #define  FAST_ROUND(d)     static_cast<INT32>(floor((d)+.5))
00165 #define  FAST_CEIL(d)      static_cast<INT32>(ceil(d))
00166 #define  FAST_FLOOR(d)     static_cast<INT32>(floor(d))
00167 #define  FAST_TRUNCATE(d)  static_cast<INT32>(d)
00168 
00169 #endif
00170 
00171 #ifndef  NO_DEPRECATED
00172 //! \deprecated Replaced by FAST_ROUND
00173 #define  ROUND FAST_ROUND
00174 #ifdef WIN32
00175 #pragma deprecated("ROUND")
00176 #endif
00177 #endif
00178 
00179 //----------------------------------------------------------------------------
00180 //    Macros for determine special floating-point values                
00181 //----------------------------------------------------------------------------
00182 
00183 /*
00184  * Determination of IEEE NaN:  On most systems, the high word is
00185  * 0x7FF8 or 0xFFF8 (high bit is sign)
00186  * The 3 systems that don't seem to conform to this rule are:
00187  *    HPUX:  High word is 0x7FF4
00188  *    SGI:   High word is 0x7FFF
00189  */
00190 
00191 #if defined(BYTEORDER_HiLo)
00192    #if defined(SGI)
00193       #define IsNaN(x) ( (x) != (x) )
00194    #elif defined(HP_APOLLO)
00195       #define IsNaN(x) ( ( ( (UINT16*)&(x) )[0] & 0x7FFF) == 0x7FF4)
00196    #else
00197       #if defined(__cplusplus)
00198          inline bool IsNaN (double x) {return ((reinterpret_cast<UINT16*>(&x)[0] & 0x7FF8) == 0x7FF8);}
00199       #else 
00200          #define IsNaN(x) ( ( ( (UINT16*)&(x) )[0] & 0x7FF8) == 0x7FF8)
00201       #endif
00202    #endif
00203 #else
00204    #if defined(__cplusplus)
00205       inline bool IsNaN (const double& x) {return ((reinterpret_cast<const UINT16*>(&x)[3] & 0x7FF8) == 0x7FF8);}
00206    #else 
00207       #define IsNaN(x) ( ( ( (UINT16*)&(x) )[3] & 0x7FF8) == 0x7FF8)
00208    #endif
00209 #endif
00210 
00211 
00212 #ifdef BYTEORDER_HiLo
00213    #if defined(__cplusplus)
00214       inline bool IsInfPos (double x) {return ((reinterpret_cast<UINT16*>(&x)[0] & 0x7FFF) == 0x7FF0);}
00215    #else 
00216       #define IsInfPos(x) ( ( ( (UINT16*)&(x) )[0] & 0x7FFF) == 0x7FF0)
00217    #endif
00218 #else
00219    #if defined(__cplusplus)
00220       inline bool IsInfPos (double x) {return ((reinterpret_cast<UINT16*>(&x)[3] & 0x7FFF) == 0x7FF0);}
00221    #else 
00222       #define IsInfPos(x) ( ( ( (UINT16*)&(x) )[3] & 0x7FFF) == 0x7FF0)
00223    #endif
00224 #endif
00225 
00226 
00227 #ifndef  NO_DEPRECATED
00228 
00229 #ifndef NAN
00230 // If already defined, assume it's a better defn
00231 #define NAN IEEE_NaN()
00232 #endif
00233 
00234 #define IND IEEE_NaN()
00235 #define INF IEEE_Infinity()
00236 #define NINF (-IEEE_Infinity())
00237 
00238 #ifdef WIN32
00239 #pragma deprecated("NAN")
00240 #pragma deprecated("IND")
00241 #pragma deprecated("INF")
00242 #pragma deprecated("NINF")
00243 #endif
00244 
00245 #endif   // NO_DEPRECATED
00246 
00247 
00248 //! Convert IEEE floating point to VAX floating point
00249 void ConvIEEEToVAX (
00250    double ieee_value,         //!< IEEE floating point value
00251    UINT8 *vax_value        //!< Pointer to 8 byte UINT8 array for VAX floating point value
00252    );
00253 
00254 //! Convert VAX floating point to IEEE floating point
00255 //!
00256 //! @return: IEEE floating point value
00257 double ConvVAXToIEEE (
00258    const UINT8 *vax_value        //!< Pointer to 8 byte UINT8 array for VAX floating point value
00259    );
00260 
00261 //!@}
00262 
00263 #undef LIBEXPORT
00264 
00265 #endif   // INC_MI32_MATH_H

Generated on Thu Apr 26 04:45:02 2007 for TNTsdk by  doxygen 1.5.2