1b8e80941Smrg/************************************************************************** 2b8e80941Smrg * 3b8e80941Smrg * Copyright 2007-2015 VMware, Inc. 4b8e80941Smrg * All Rights Reserved. 5b8e80941Smrg * 6b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 7b8e80941Smrg * copy of this software and associated documentation files (the 8b8e80941Smrg * "Software"), to deal in the Software without restriction, including 9b8e80941Smrg * without limitation the rights to use, copy, modify, merge, publish, 10b8e80941Smrg * distribute, sub license, and/or sell copies of the Software, and to 11b8e80941Smrg * permit persons to whom the Software is furnished to do so, subject to 12b8e80941Smrg * the following conditions: 13b8e80941Smrg * 14b8e80941Smrg * The above copyright notice and this permission notice (including the 15b8e80941Smrg * next paragraph) shall be included in all copies or substantial portions 16b8e80941Smrg * of the Software. 17b8e80941Smrg * 18b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19b8e80941Smrg * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20b8e80941Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21b8e80941Smrg * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 22b8e80941Smrg * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23b8e80941Smrg * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24b8e80941Smrg * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25b8e80941Smrg * 26b8e80941Smrg **************************************************************************/ 27b8e80941Smrg 28b8e80941Smrg/** 29b8e80941Smrg * Wrapper for math.h which makes sure we have definitions of all the c99 30b8e80941Smrg * functions. 31b8e80941Smrg */ 32b8e80941Smrg 33b8e80941Smrg 34b8e80941Smrg#ifndef _C99_MATH_H_ 35b8e80941Smrg#define _C99_MATH_H_ 36b8e80941Smrg 37b8e80941Smrg#include <math.h> 38b8e80941Smrg#include "c99_compat.h" 39b8e80941Smrg 40b8e80941Smrg 41b8e80941Smrg/* This is to ensure that we get M_PI, etc. definitions */ 42b8e80941Smrg#if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES) 43b8e80941Smrg#error _USE_MATH_DEFINES define required when building with MSVC 44b8e80941Smrg#endif 45b8e80941Smrg 46b8e80941Smrg 47b8e80941Smrg#if !defined(_MSC_VER) && \ 48b8e80941Smrg __STDC_VERSION__ < 199901L && \ 49b8e80941Smrg (!defined(_XOPEN_SOURCE) || _XOPEN_SOURCE < 600) && \ 50b8e80941Smrg !defined(__cplusplus) 51b8e80941Smrg 52b8e80941Smrgstatic inline long int 53b8e80941Smrglrint(double d) 54b8e80941Smrg{ 55b8e80941Smrg long int rounded = (long int)(d + 0.5); 56b8e80941Smrg 57b8e80941Smrg if (d - floor(d) == 0.5) { 58b8e80941Smrg if (rounded % 2 != 0) 59b8e80941Smrg rounded += (d > 0) ? -1 : 1; 60b8e80941Smrg } 61b8e80941Smrg 62b8e80941Smrg return rounded; 63b8e80941Smrg} 64b8e80941Smrg 65b8e80941Smrgstatic inline long int 66b8e80941Smrglrintf(float f) 67b8e80941Smrg{ 68b8e80941Smrg long int rounded = (long int)(f + 0.5f); 69b8e80941Smrg 70b8e80941Smrg if (f - floorf(f) == 0.5f) { 71b8e80941Smrg if (rounded % 2 != 0) 72b8e80941Smrg rounded += (f > 0) ? -1 : 1; 73b8e80941Smrg } 74b8e80941Smrg 75b8e80941Smrg return rounded; 76b8e80941Smrg} 77b8e80941Smrg 78b8e80941Smrgstatic inline long long int 79b8e80941Smrgllrint(double d) 80b8e80941Smrg{ 81b8e80941Smrg long long int rounded = (long long int)(d + 0.5); 82b8e80941Smrg 83b8e80941Smrg if (d - floor(d) == 0.5) { 84b8e80941Smrg if (rounded % 2 != 0) 85b8e80941Smrg rounded += (d > 0) ? -1 : 1; 86b8e80941Smrg } 87b8e80941Smrg 88b8e80941Smrg return rounded; 89b8e80941Smrg} 90b8e80941Smrg 91b8e80941Smrgstatic inline long long int 92b8e80941Smrgllrintf(float f) 93b8e80941Smrg{ 94b8e80941Smrg long long int rounded = (long long int)(f + 0.5f); 95b8e80941Smrg 96b8e80941Smrg if (f - floorf(f) == 0.5f) { 97b8e80941Smrg if (rounded % 2 != 0) 98b8e80941Smrg rounded += (f > 0) ? -1 : 1; 99b8e80941Smrg } 100b8e80941Smrg 101b8e80941Smrg return rounded; 102b8e80941Smrg} 103b8e80941Smrg 104b8e80941Smrgstatic inline float 105b8e80941Smrgexp2f(float f) 106b8e80941Smrg{ 107b8e80941Smrg return powf(2.0f, f); 108b8e80941Smrg} 109b8e80941Smrg 110b8e80941Smrgstatic inline double 111b8e80941Smrgexp2(double d) 112b8e80941Smrg{ 113b8e80941Smrg return pow(2.0, d); 114b8e80941Smrg} 115b8e80941Smrg 116b8e80941Smrg#endif /* C99 */ 117b8e80941Smrg 118b8e80941Smrg 119b8e80941Smrg/* 120b8e80941Smrg * signbit() is a macro on Linux. Not available on Windows. 121b8e80941Smrg */ 122b8e80941Smrg#ifndef signbit 123b8e80941Smrg#define signbit(x) ((x) < 0.0f) 124b8e80941Smrg#endif 125b8e80941Smrg 126b8e80941Smrg 127b8e80941Smrg#ifndef M_PI 128b8e80941Smrg#define M_PI (3.14159265358979323846) 129b8e80941Smrg#endif 130b8e80941Smrg 131b8e80941Smrg#ifndef M_E 132b8e80941Smrg#define M_E (2.7182818284590452354) 133b8e80941Smrg#endif 134b8e80941Smrg 135b8e80941Smrg#ifndef M_LOG2E 136b8e80941Smrg#define M_LOG2E (1.4426950408889634074) 137b8e80941Smrg#endif 138b8e80941Smrg 139b8e80941Smrg#ifndef FLT_MAX_EXP 140b8e80941Smrg#define FLT_MAX_EXP 128 141b8e80941Smrg#endif 142b8e80941Smrg 143b8e80941Smrg 144b8e80941Smrg#if defined(fpclassify) 145b8e80941Smrg/* ISO C99 says that fpclassify is a macro. Assume that any implementation 146b8e80941Smrg * of fpclassify, whether it's in a C99 compiler or not, will be a macro. 147b8e80941Smrg */ 148b8e80941Smrg#elif defined(__cplusplus) 149b8e80941Smrg/* For C++, fpclassify() should be defined in <cmath> */ 150b8e80941Smrg#elif defined(_MSC_VER) 151b8e80941Smrg/* Not required on VS2013 and above. Oddly, the fpclassify() function 152b8e80941Smrg * doesn't exist in such a form on MSVC. This is an implementation using 153b8e80941Smrg * slightly different lower-level Windows functions. 154b8e80941Smrg */ 155b8e80941Smrg#include <float.h> 156b8e80941Smrg 157b8e80941Smrgstatic inline enum {FP_NAN, FP_INFINITE, FP_ZERO, FP_SUBNORMAL, FP_NORMAL} 158b8e80941Smrgfpclassify(double x) 159b8e80941Smrg{ 160b8e80941Smrg switch(_fpclass(x)) { 161b8e80941Smrg case _FPCLASS_SNAN: /* signaling NaN */ 162b8e80941Smrg case _FPCLASS_QNAN: /* quiet NaN */ 163b8e80941Smrg return FP_NAN; 164b8e80941Smrg case _FPCLASS_NINF: /* negative infinity */ 165b8e80941Smrg case _FPCLASS_PINF: /* positive infinity */ 166b8e80941Smrg return FP_INFINITE; 167b8e80941Smrg case _FPCLASS_NN: /* negative normal */ 168b8e80941Smrg case _FPCLASS_PN: /* positive normal */ 169b8e80941Smrg return FP_NORMAL; 170b8e80941Smrg case _FPCLASS_ND: /* negative denormalized */ 171b8e80941Smrg case _FPCLASS_PD: /* positive denormalized */ 172b8e80941Smrg return FP_SUBNORMAL; 173b8e80941Smrg case _FPCLASS_NZ: /* negative zero */ 174b8e80941Smrg case _FPCLASS_PZ: /* positive zero */ 175b8e80941Smrg return FP_ZERO; 176b8e80941Smrg default: 177b8e80941Smrg /* Should never get here; but if we do, this will guarantee 178b8e80941Smrg * that the pattern is not treated like a number. 179b8e80941Smrg */ 180b8e80941Smrg return FP_NAN; 181b8e80941Smrg } 182b8e80941Smrg} 183b8e80941Smrg#else 184b8e80941Smrg#error "Need to include or define an fpclassify function" 185b8e80941Smrg#endif 186b8e80941Smrg 187b8e80941Smrg 188b8e80941Smrg/* Since C++11, the following functions are part of the std namespace. Their C 189b8e80941Smrg * counteparts should still exist in the global namespace, however cmath 190b8e80941Smrg * undefines those functions, which in glibc 2.23, are defined as macros rather 191b8e80941Smrg * than functions as in glibc 2.22. 192b8e80941Smrg */ 193b8e80941Smrg#if __cplusplus >= 201103L && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 23)) 194b8e80941Smrg#include <cmath> 195b8e80941Smrg 196b8e80941Smrgusing std::fpclassify; 197b8e80941Smrgusing std::isfinite; 198b8e80941Smrgusing std::isinf; 199b8e80941Smrgusing std::isnan; 200b8e80941Smrgusing std::isnormal; 201b8e80941Smrgusing std::signbit; 202b8e80941Smrgusing std::isgreater; 203b8e80941Smrgusing std::isgreaterequal; 204b8e80941Smrgusing std::isless; 205b8e80941Smrgusing std::islessequal; 206b8e80941Smrgusing std::islessgreater; 207b8e80941Smrgusing std::isunordered; 208b8e80941Smrg#endif 209b8e80941Smrg 210b8e80941Smrg 211b8e80941Smrg#endif /* #define _C99_MATH_H_ */ 212