// Filename: cmath.I // Created by: drose (19May00) // //////////////////////////////////////////////////////////////////// // // PANDA 3D SOFTWARE // Copyright (c) Carnegie Mellon University. All rights reserved. // // All use of this software is subject to the terms of the revised BSD // license. You should have received a copy of this license along // with this source code in a file named "LICENSE." // //////////////////////////////////////////////////////////////////// #ifdef __APPLE__ #ifndef isnan #define isnan(x) \ ((sizeof(x) == sizeof(double)) ? \ __isnand(x) : \ (sizeof(x) == sizeof(float)) ? __isnanf(x) : __isnan(x)) #endif #endif #ifdef __INTEL_COMPILER // see float.h #define FPU_CONTROLWORD_WRITEMASK 0xFFFFF // if you look at defn of _CW_DEFAULT, all settings fall within 0xFFFFF #define FPU_CONTROLWORD_NEW_SETTING _CW_DEFAULT #endif //////////////////////////////////////////////////////////////////// // Function: csqrt // Description: //////////////////////////////////////////////////////////////////// INLINE float csqrt(float v) { return sqrtf(v); } //////////////////////////////////////////////////////////////////// // Function: csin // Description: //////////////////////////////////////////////////////////////////// INLINE float csin(float v) { return sinf(v); } //////////////////////////////////////////////////////////////////// // Function: ccos // Description: //////////////////////////////////////////////////////////////////// INLINE float ccos(float v) { return cosf(v); } //////////////////////////////////////////////////////////////////// // Function: ctan // Description: //////////////////////////////////////////////////////////////////// INLINE float ctan(float v) { return tanf(v); } //////////////////////////////////////////////////////////////////// // Function: csincos // Description: //////////////////////////////////////////////////////////////////// INLINE void csincos(float v, float *sin_result, float *cos_result) { // MS VC defines _M_IX86 for x86. gcc should define _X86_ #if defined(_M_IX86) || defined(_X86_) //#define fsincos_opcode __asm _emit 0xd9 __asm _emit 0xfb __asm { mov eax, sin_result mov edx, cos_result fld v fsincos fstp DWORD ptr [edx] fstp DWORD ptr [eax] } #else //!_X86_ *sin_result = sinf(v); *cos_result = cosf(v); #endif //!_X86_ } //////////////////////////////////////////////////////////////////// // Function: csin_over_x // Description: Computes sin(x) / x, well-behaved as x approaches 0. //////////////////////////////////////////////////////////////////// INLINE float csin_over_x(float v) { if (1.0f + v * v == 1.0f) { return 1.0f; } else { return csin(v) / v; } } //////////////////////////////////////////////////////////////////// // Function: cabs // Description: //////////////////////////////////////////////////////////////////// INLINE float cabs(float v) { return fabs(v); } //////////////////////////////////////////////////////////////////// // Function: catan // Description: //////////////////////////////////////////////////////////////////// INLINE float catan(float v) { return atanf(v); } //////////////////////////////////////////////////////////////////// // Function: catan2 // Description: //////////////////////////////////////////////////////////////////// INLINE float catan2(float y, float x) { return atan2f(y, x); } //////////////////////////////////////////////////////////////////// // Function: casin // Description: //////////////////////////////////////////////////////////////////// INLINE float casin(float v) { return asinf(v); } //////////////////////////////////////////////////////////////////// // Function: cacos // Description: //////////////////////////////////////////////////////////////////// INLINE float cacos(float v) { return acosf(v); } //////////////////////////////////////////////////////////////////// // Function: cmod // Description: This is similar to fmod(), but it behaves properly // when x is negative: that is, it always returns a // value in the range [0, y), assuming y is positive. //////////////////////////////////////////////////////////////////// INLINE float cmod(float x, float y) { return x - cfloor(x / y) * y; } //////////////////////////////////////////////////////////////////// // Function: cfloor // Description: //////////////////////////////////////////////////////////////////// INLINE double cfloor(double f) { #ifdef __INTEL_COMPILER // intel floor doesnt work right if fpu mode is not double, so make double-prec mode is on unsigned int saved_fpu_control_word=_controlfp(0x0,0x0); _controlfp(FPU_CONTROLWORD_NEW_SETTING,FPU_CONTROLWORD_WRITEMASK); double retval=floor(f); _controlfp(saved_fpu_control_word,FPU_CONTROLWORD_WRITEMASK); return retval; #else return floor(f); #endif } //////////////////////////////////////////////////////////////////// // Function: cceil // Description: //////////////////////////////////////////////////////////////////// INLINE double cceil(double f) { #ifdef __INTEL_COMPILER // intel ceil doesnt work right if fpu mode is not double, so make double-prec mode is on unsigned int saved_fpu_control_word=_controlfp(0x0,0x0); _controlfp(FPU_CONTROLWORD_NEW_SETTING,FPU_CONTROLWORD_WRITEMASK); double retval=ceil(f); _controlfp(saved_fpu_control_word,FPU_CONTROLWORD_WRITEMASK); return retval; #else return ceil(f); #endif } //////////////////////////////////////////////////////////////////// // Function: cfrac // Description: Returns the fractional component of f: f - cfloor(f). //////////////////////////////////////////////////////////////////// INLINE double cfrac(double f) { return f - cfloor(f); } //////////////////////////////////////////////////////////////////// // Function: csqrt // Description: //////////////////////////////////////////////////////////////////// INLINE double csqrt(double v) { return sqrt(v); } //////////////////////////////////////////////////////////////////// // Function: csin // Description: //////////////////////////////////////////////////////////////////// INLINE double csin(double v) { return sin(v); } //////////////////////////////////////////////////////////////////// // Function: ccos // Description: //////////////////////////////////////////////////////////////////// INLINE double ccos(double v) { return cos(v); } //////////////////////////////////////////////////////////////////// // Function: ctan // Description: //////////////////////////////////////////////////////////////////// INLINE double ctan(double v) { return tan(v); } //////////////////////////////////////////////////////////////////// // Function: csincos // Description: //////////////////////////////////////////////////////////////////// INLINE void csincos(double v, double *sin_result, double *cos_result) { #if defined(_M_IX86) || defined(_X86_) //#define fsincos_opcode __asm _emit 0xd9 __asm _emit 0xfb __asm { mov eax, sin_result mov edx, cos_result fld v fsincos fstp QWORD ptr [edx] fstp QWORD ptr [eax] } #else //!_X86_ *sin_result = sin(v); *cos_result = cos(v); #endif //!_X86_ } //////////////////////////////////////////////////////////////////// // Function: csin_over_x // Description: Computes sin(x) / x, well-behaved as x approaches 0. //////////////////////////////////////////////////////////////////// INLINE double csin_over_x(double v) { if (1.0 + v * v == 1.0) { return 1.0; } else { return csin(v) / v; } } //////////////////////////////////////////////////////////////////// // Function: cabs // Description: //////////////////////////////////////////////////////////////////// INLINE double cabs(double v) { return fabs(v); } //////////////////////////////////////////////////////////////////// // Function: catan // Description: //////////////////////////////////////////////////////////////////// INLINE double catan(double v) { return atan(v); } //////////////////////////////////////////////////////////////////// // Function: catan2 // Description: //////////////////////////////////////////////////////////////////// INLINE double catan2(double y, double x) { return atan2(y, x); } //////////////////////////////////////////////////////////////////// // Function: casin // Description: //////////////////////////////////////////////////////////////////// INLINE double casin(double v) { return asin(v); } //////////////////////////////////////////////////////////////////// // Function: cacos // Description: //////////////////////////////////////////////////////////////////// INLINE double cacos(double v) { return acos(v); } //////////////////////////////////////////////////////////////////// // Function: cmod // Description: This is similar to fmod(), but it behaves properly // when x is negative: that is, it always returns a // value in the range [0, y), assuming y is positive. //////////////////////////////////////////////////////////////////// INLINE double cmod(double x, double y) { return x - cfloor(x / y) * y; } //////////////////////////////////////////////////////////////////// // Function: cnan // Description: //////////////////////////////////////////////////////////////////// INLINE bool cnan(double v) { #ifndef _WIN32 return (isnan(v) != 0); #else return (_isnan(v) != 0); #endif } //////////////////////////////////////////////////////////////////// // Function: cmod // Description: This is similar to fmod(), but it behaves properly // when x is negative: that is, it always returns a // value in the range [0, y), assuming y is positive. // // This integer-valued function is provided since the // built-in modulo operator % does not work properly for // negative x. //////////////////////////////////////////////////////////////////// INLINE int cmod(int x, int y) { if (x < 0) { return y - 1 - ((-x - 1) % y); } else { return x % y; } }