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