/**************************************************************************1*2* Copyright 2007-2015 VMware, Inc.3* All Rights Reserved.4*5* Permission is hereby granted, free of charge, to any person obtaining a6* copy of this software and associated documentation files (the7* "Software"), to deal in the Software without restriction, including8* without limitation the rights to use, copy, modify, merge, publish,9* distribute, sub license, and/or sell copies of the Software, and to10* permit persons to whom the Software is furnished to do so, subject to11* the following conditions:12*13* The above copyright notice and this permission notice (including the14* next paragraph) shall be included in all copies or substantial portions15* of the Software.16*17* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS18* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF19* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.20* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR21* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,22* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE23* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.24*25**************************************************************************/2627/**28* Wrapper for math.h which makes sure we have definitions of all the c9929* functions.30*/313233#ifndef _C99_MATH_H_34#define _C99_MATH_H_3536#include <math.h>37#include "c99_compat.h"383940/* This is to ensure that we get M_PI, etc. definitions */41#if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES)42#error _USE_MATH_DEFINES define required when building with MSVC43#endif444546#if !defined(_MSC_VER) && \47__STDC_VERSION__ < 199901L && \48(!defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600) && \49!defined(__cplusplus)5051static inline long int52lrint(double d)53{54long int rounded = (long int)(d + 0.5);5556if (d - floor(d) == 0.5) {57if (rounded % 2 != 0)58rounded += (d > 0) ? -1 : 1;59}6061return rounded;62}6364static inline long int65lrintf(float f)66{67long int rounded = (long int)(f + 0.5f);6869if (f - floorf(f) == 0.5f) {70if (rounded % 2 != 0)71rounded += (f > 0) ? -1 : 1;72}7374return rounded;75}7677static inline long long int78llrint(double d)79{80long long int rounded = (long long int)(d + 0.5);8182if (d - floor(d) == 0.5) {83if (rounded % 2 != 0)84rounded += (d > 0) ? -1 : 1;85}8687return rounded;88}8990static inline long long int91llrintf(float f)92{93long long int rounded = (long long int)(f + 0.5f);9495if (f - floorf(f) == 0.5f) {96if (rounded % 2 != 0)97rounded += (f > 0) ? -1 : 1;98}99100return rounded;101}102103static inline float104exp2f(float f)105{106return powf(2.0f, f);107}108109static inline double110exp2(double d)111{112return pow(2.0, d);113}114115#endif /* C99 */116117118/*119* signbit() is a macro on Linux. Not available on Windows.120*/121#ifndef signbit122#define signbit(x) ((x) < 0.0f)123#endif124125126#ifndef M_PI127#define M_PI (3.14159265358979323846)128#endif129130#ifndef M_E131#define M_E (2.7182818284590452354)132#endif133134#ifndef M_LOG2E135#define M_LOG2E (1.4426950408889634074)136#endif137138#ifndef FLT_MAX_EXP139#define FLT_MAX_EXP 128140#endif141142143#if defined(fpclassify)144/* ISO C99 says that fpclassify is a macro. Assume that any implementation145* of fpclassify, whether it's in a C99 compiler or not, will be a macro.146*/147#elif defined(__cplusplus)148/* For C++, fpclassify() should be defined in <cmath> */149#elif defined(_MSC_VER)150/* Not required on VS2013 and above. Oddly, the fpclassify() function151* doesn't exist in such a form on MSVC. This is an implementation using152* slightly different lower-level Windows functions.153*/154#include <float.h>155156static inline enum {FP_NAN, FP_INFINITE, FP_ZERO, FP_SUBNORMAL, FP_NORMAL}157fpclassify(double x)158{159switch(_fpclass(x)) {160case _FPCLASS_SNAN: /* signaling NaN */161case _FPCLASS_QNAN: /* quiet NaN */162return FP_NAN;163case _FPCLASS_NINF: /* negative infinity */164case _FPCLASS_PINF: /* positive infinity */165return FP_INFINITE;166case _FPCLASS_NN: /* negative normal */167case _FPCLASS_PN: /* positive normal */168return FP_NORMAL;169case _FPCLASS_ND: /* negative denormalized */170case _FPCLASS_PD: /* positive denormalized */171return FP_SUBNORMAL;172case _FPCLASS_NZ: /* negative zero */173case _FPCLASS_PZ: /* positive zero */174return FP_ZERO;175default:176/* Should never get here; but if we do, this will guarantee177* that the pattern is not treated like a number.178*/179return FP_NAN;180}181}182#else183#error "Need to include or define an fpclassify function"184#endif185186187/* Since C++11, the following functions are part of the std namespace. Their C188* counteparts should still exist in the global namespace, however cmath189* undefines those functions, which in glibc 2.23, are defined as macros rather190* than functions as in glibc 2.22.191*/192#if __cplusplus >= 201103L && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 23))193#include <cmath>194195using std::fpclassify;196using std::isfinite;197using std::isinf;198using std::isnan;199using std::isnormal;200using std::signbit;201using std::isgreater;202using std::isgreaterequal;203using std::isless;204using std::islessequal;205using std::islessgreater;206using std::isunordered;207#endif208209210#endif /* #define _C99_MATH_H_ */211212213