X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=include%2Fc99_math.h;h=e906c26aa543bc1adfd1bc341aba47886442466b;hb=5f99c490089cae28de7226946d726f158838f8b9;hp=35173c68d1c0637c90961f392dc488672d1aae2d;hpb=06ed81044fc6b1dee90e67de314f81150746e104;p=mesa.git diff --git a/include/c99_math.h b/include/c99_math.h index 35173c68d1c..e906c26aa54 100644 --- a/include/c99_math.h +++ b/include/c99_math.h @@ -38,50 +38,17 @@ #include "c99_compat.h" -#if defined(_MSC_VER) - /* This is to ensure that we get M_PI, etc. definitions */ -#if !defined(_USE_MATH_DEFINES) +#if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES) #error _USE_MATH_DEFINES define required when building with MSVC #endif -#if _MSC_VER < 1800 -#define isfinite(x) _finite((double)(x)) -#define isnan(x) _isnan((double)(x)) -#endif /* _MSC_VER < 1800 */ -#if _MSC_VER < 1800 -static inline double log2( double x ) -{ - const double invln2 = 1.442695041; - return log( x ) * invln2; -} +#if !defined(_MSC_VER) && \ + __STDC_VERSION__ < 199901L && \ + (!defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600) && \ + !defined(__cplusplus) -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) { @@ -133,6 +100,19 @@ 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 */ @@ -156,5 +136,76 @@ llrintf(float f) #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_ */