diff --git a/src/math_private.h b/src/math_private.h index 43781b4..5903e13 100644 --- a/src/math_private.h +++ b/src/math_private.h @@ -227,86 +227,6 @@ do { \ * Common routine to process the arguments to nan(), nanf(), and nanl(). */ void _scan_nan(u_int32_t *__words, int __num_words, const char *__s); - -//VBS -//#ifdef _COMPLEX_H - -/* - * C99 specifies that complex numbers have the same representation as - * an array of two elements, where the first element is the real part - * and the second element is the imaginary part. - */ -typedef union { - float complex f; - float a[2]; -} float_complex; -typedef union { - double complex f; - double a[2]; -} double_complex; -typedef union { - long double complex f; - long double a[2]; -} long_double_complex; -#define REALPART(z) ((z).a[0]) -#define IMAGPART(z) ((z).a[1]) - -/* - * Inline functions that can be used to construct complex values. - * - * The C99 standard intends x+I*y to be used for this, but x+I*y is - * currently unusable in general since gcc introduces many overflow, - * underflow, sign and efficiency bugs by rewriting I*y as - * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product. - * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted - * to -0.0+I*0.0. - * - * In C11, a CMPLX(x,y) macro was added to circumvent this limitation, - * and gcc 4.7 added a __builtin_complex feature to simplify implementation - * of CMPLX in libc, so we can take advantage of these features if they - * are available. - */ -#if defined(CMPLXF) && defined(CMPLX) && defined(CMPLXL) /* C11 */ -# define cpackf(x,y) CMPLXF(x,y) -# define cpack(x,y) CMPLX(x,y) -# define cpackl(x,y) CMPLXL(x,y) -#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__INTEL_COMPILER) -# define cpackf(x,y) __builtin_complex ((float) (x), (float) (y)) -# define cpack(x,y) __builtin_complex ((double) (x), (double) (y)) -# define cpackl(x,y) __builtin_complex ((long double) (x), (long double) (y)) -#else /* define our own cpack functions */ -static __inline float complex -cpackf(float x, float y) -{ - float_complex z; - - REALPART(z) = x; - IMAGPART(z) = y; - return (z.f); -} - -static __inline double complex -cpack(double x, double y) -{ - double_complex z; - - REALPART(z) = x; - IMAGPART(z) = y; - return (z.f); -} - -static __inline long double complex -cpackl(long double x, long double y) -{ - long_double_complex z; - - REALPART(z) = x; - IMAGPART(z) = y; - return (z.f); -} -#endif /* define our own cpack functions */ -//VBS -//#endif /* _COMPLEX_H */ #ifdef __GNUCLIKE_ASM diff --git a/src/openlibm.h b/src/openlibm.h index 5e6ba5d..11f85cf 100644 --- a/src/openlibm.h +++ b/src/openlibm.h @@ -17,6 +17,7 @@ #ifndef _MATH_H_ #define _MATH_H_ +#include #include "cdefs-compat.h" #include "types-compat.h" @@ -167,6 +168,86 @@ extern int signgam; #endif #endif /* __BSD_VISIBLE */ +//VBS +//#ifdef _COMPLEX_H + +/* + * C99 specifies that complex numbers have the same representation as + * an array of two elements, where the first element is the real part + * and the second element is the imaginary part. + */ +typedef union { + float complex f; + float a[2]; +} float_complex; +typedef union { + double complex f; + double a[2]; +} double_complex; +typedef union { + long double complex f; + long double a[2]; +} long_double_complex; +#define REALPART(z) ((z).a[0]) +#define IMAGPART(z) ((z).a[1]) + +/* + * Inline functions that can be used to construct complex values. + * + * The C99 standard intends x+I*y to be used for this, but x+I*y is + * currently unusable in general since gcc introduces many overflow, + * underflow, sign and efficiency bugs by rewriting I*y as + * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product. + * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted + * to -0.0+I*0.0. + * + * In C11, a CMPLX(x,y) macro was added to circumvent this limitation, + * and gcc 4.7 added a __builtin_complex feature to simplify implementation + * of CMPLX in libc, so we can take advantage of these features if they + * are available. + */ +#if defined(CMPLXF) && defined(CMPLX) && defined(CMPLXL) /* C11 */ +# define cpackf(x,y) CMPLXF(x,y) +# define cpack(x,y) CMPLX(x,y) +# define cpackl(x,y) CMPLXL(x,y) +#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__INTEL_COMPILER) +# define cpackf(x,y) __builtin_complex ((float) (x), (float) (y)) +# define cpack(x,y) __builtin_complex ((double) (x), (double) (y)) +# define cpackl(x,y) __builtin_complex ((long double) (x), (long double) (y)) +#else /* define our own cpack functions */ +static __inline float complex +cpackf(float x, float y) +{ + float_complex z; + + REALPART(z) = x; + IMAGPART(z) = y; + return (z.f); +} + +static __inline double complex +cpack(double x, double y) +{ + double_complex z; + + REALPART(z) = x; + IMAGPART(z) = y; + return (z.f); +} + +static __inline long double complex +cpackl(long double x, long double y) +{ + long_double_complex z; + + REALPART(z) = x; + IMAGPART(z) = y; + return (z.f); +} +#endif /* define our own cpack functions */ +//VBS +//#endif /* _COMPLEX_H */ + /* * Most of these functions depend on the rounding mode and have the side * effect of raising floating-point exceptions, so they are not declared diff --git a/src/s_cimag.c b/src/s_cimag.c index 3b69c14..99835bf 100644 --- a/src/s_cimag.c +++ b/src/s_cimag.c @@ -27,6 +27,7 @@ */ #include +#include "openlibm.h" #include "math_private.h" DLLEXPORT double diff --git a/src/s_cimagf.c b/src/s_cimagf.c index 1453cac..a3d3c86 100644 --- a/src/s_cimagf.c +++ b/src/s_cimagf.c @@ -27,6 +27,7 @@ */ #include +#include "openlibm.h" #include "math_private.h" DLLEXPORT float diff --git a/src/s_cimagl.c b/src/s_cimagl.c index 5f8876c..58d1990 100644 --- a/src/s_cimagl.c +++ b/src/s_cimagl.c @@ -27,6 +27,7 @@ */ #include +#include "openlibm.h" #include "math_private.h" DLLEXPORT long double