2005-09-21 23:50:36 +00:00

354 lines
10 KiB
Plaintext

// Filename: cmath.I
// Created by: drose (19May00)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifdef __APPLE__
#define isnan(x) \
((sizeof(x) == sizeof(double)) ? \
__isnand(x) : \
(sizeof(x) == sizeof(float)) ? __isnanf(x) : __isnan(x))
#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: 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;
}
}