X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=include%2Fc99_math.h;h=e906c26aa543bc1adfd1bc341aba47886442466b;hb=565df656513acec8c2d5fe915c51b4b901265fa7;hp=147bceed96d46a0406d557540155fc241ed2c2bf;hpb=79b480ccc069b92d4614ed7f61d810bdc816cb7c;p=mesa.git diff --git a/include/c99_math.h b/include/c99_math.h index 147bceed96d..e906c26aa54 100644 --- a/include/c99_math.h +++ b/include/c99_math.h @@ -38,116 +38,17 @@ #include "c99_compat.h" -#if defined(_MSC_VER) +/* This is to ensure that we get M_PI, etc. definitions */ +#if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES) +#error _USE_MATH_DEFINES define required when building with MSVC +#endif -#if _MSC_VER < 1400 && !defined(__cplusplus) -static inline float cosf( float f ) -{ - return (float) cos( (double) f ); -} - -static inline float sinf( float f ) -{ - return (float) sin( (double) f ); -} - -static inline float ceilf( float f ) -{ - return (float) ceil( (double) f ); -} - -static inline float floorf( float f ) -{ - return (float) floor( (double) f ); -} - -static inline float powf( float f, float g ) -{ - return (float) pow( (double) f, (double) g ); -} - -static inline float sqrtf( float f ) -{ - return (float) sqrt( (double) f ); -} - -static inline float fabsf( float f ) -{ - return (float) fabs( (double) f ); -} - -static inline float logf( float f ) -{ - return (float) log( (double) f ); -} +#if !defined(_MSC_VER) && \ + __STDC_VERSION__ < 199901L && \ + (!defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600) && \ + !defined(__cplusplus) -static inline float frexpf(float x, int *exp) -{ - return (float) frexp(x, exp); -} - -static inline float ldexpf(float x, int exp) -{ - return (float) ldexp(x, exp); -} - -static inline float logf(float x) -{ - return (float) log(x); -} - -static inline float expf(float x) -{ - return (float) exp(x); -} - - -#else -/* Work-around an extra semi-colon in VS 2005 logf definition */ -#ifdef logf -#undef logf -#define logf(x) ((float)log((double)(x))) -#endif /* logf */ - -#if _MSC_VER < 1800 -#define isfinite(x) _finite((double)(x)) -#define isnan(x) _isnan((double)(x)) -#endif /* _MSC_VER < 1800 */ -#endif /* _MSC_VER < 1400 && !defined(__cplusplus) */ - -#if _MSC_VER < 1800 -static inline double log2( double x ) -{ - const double invln2 = 1.442695041; - return log( x ) * invln2; -} - -static inline double -round(double x) -{ - return x >= 0.0 ? floor(x + 0.5) : ceil(x - 0.5); -} - -static inline float -roundf(float x) -{ - return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f); -} -#endif - -#ifndef INFINITY -#define INFINITY (DBL_MAX + DBL_MAX) -#endif - -#ifndef NAN -#define NAN (INFINITY - INFINITY) -#endif - -#endif /* _MSC_VER */ - - -#if __STDC_VERSION__ < 199901L && (!defined(__cplusplus) || defined(_MSC_VER)) static inline long int lrint(double d) { @@ -199,7 +100,112 @@ llrintf(float f) return rounded; } + +static inline float +exp2f(float f) +{ + return powf(2.0f, f); +} + +static inline double +exp2(double d) +{ + return pow(2.0, d); +} + #endif /* C99 */ +/* + * signbit() is a macro on Linux. Not available on Windows. + */ +#ifndef signbit +#define signbit(x) ((x) < 0.0f) +#endif + + +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + +#ifndef M_E +#define M_E (2.7182818284590452354) +#endif + +#ifndef M_LOG2E +#define M_LOG2E (1.4426950408889634074) +#endif + +#ifndef FLT_MAX_EXP +#define FLT_MAX_EXP 128 +#endif + + +#if defined(fpclassify) +/* ISO C99 says that fpclassify is a macro. Assume that any implementation + * of fpclassify, whether it's in a C99 compiler or not, will be a macro. + */ +#elif defined(__cplusplus) +/* For C++, fpclassify() should be defined in */ +#elif defined(_MSC_VER) +/* Not required on VS2013 and above. Oddly, the fpclassify() function + * doesn't exist in such a form on MSVC. This is an implementation using + * slightly different lower-level Windows functions. + */ +#include + +static inline enum {FP_NAN, FP_INFINITE, FP_ZERO, FP_SUBNORMAL, FP_NORMAL} +fpclassify(double x) +{ + switch(_fpclass(x)) { + case _FPCLASS_SNAN: /* signaling NaN */ + case _FPCLASS_QNAN: /* quiet NaN */ + return FP_NAN; + case _FPCLASS_NINF: /* negative infinity */ + case _FPCLASS_PINF: /* positive infinity */ + return FP_INFINITE; + case _FPCLASS_NN: /* negative normal */ + case _FPCLASS_PN: /* positive normal */ + return FP_NORMAL; + case _FPCLASS_ND: /* negative denormalized */ + case _FPCLASS_PD: /* positive denormalized */ + return FP_SUBNORMAL; + case _FPCLASS_NZ: /* negative zero */ + case _FPCLASS_PZ: /* positive zero */ + return FP_ZERO; + default: + /* Should never get here; but if we do, this will guarantee + * that the pattern is not treated like a number. + */ + return FP_NAN; + } +} +#else +#error "Need to include or define an fpclassify function" +#endif + + +/* Since C++11, the following functions are part of the std namespace. Their C + * counteparts should still exist in the global namespace, however cmath + * undefines those functions, which in glibc 2.23, are defined as macros rather + * than functions as in glibc 2.22. + */ +#if __cplusplus >= 201103L && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 23)) +#include + +using std::fpclassify; +using std::isfinite; +using std::isinf; +using std::isnan; +using std::isnormal; +using std::signbit; +using std::isgreater; +using std::isgreaterequal; +using std::isless; +using std::islessequal; +using std::islessgreater; +using std::isunordered; +#endif + + #endif /* #define _C99_MATH_H_ */