mirror of
https://git.planet-casio.com/Lephenixnoir/OpenLibm.git
synced 2024-12-29 13:03:42 +01:00
Move CMPLX() into <openlibm_complex.h>, as it is normally part of <complex.h>.
While there, make CMPLX() work with Clang by using compound literals. Now that cimag*() uses __imag__, we can also just inline the unions. There is no need for the separate types anymore. Also just define CMPLX() unconditionally now, as we no longer pull in the host's <complex.h>.
This commit is contained in:
parent
a249c5ebb3
commit
410e6ebb59
2 changed files with 68 additions and 98 deletions
|
@ -17,8 +17,6 @@
|
|||
#ifndef OPENLIBM_H
|
||||
#define OPENLIBM_H
|
||||
|
||||
#include <openlibm_complex.h>
|
||||
|
||||
#if (defined(_WIN32) || defined (_MSC_VER)) && !defined(__WIN32__)
|
||||
#define __WIN32__
|
||||
#endif
|
||||
|
@ -180,102 +178,6 @@ 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])
|
||||
|
||||
/*
|
||||
* Macros 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 __builtin_complex is not available, resort to using inline
|
||||
* functions instead. These can unfortunately not be used to construct
|
||||
* compile-time constants.
|
||||
*/
|
||||
|
||||
#define HAVE_BUILTIN_COMPLEX (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__INTEL_COMPILER)
|
||||
|
||||
#ifndef CMPLXF
|
||||
#if HAVE_BUILTIN_COMPLEX
|
||||
# define CMPLXF(x,y) __builtin_complex ((float) (x), (float) (y))
|
||||
#else
|
||||
static __inline float complex
|
||||
CMPLXF(float x, float y)
|
||||
{
|
||||
float_complex z;
|
||||
|
||||
REALPART(z) = x;
|
||||
IMAGPART(z) = y;
|
||||
return (z.f);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CMPLX
|
||||
#if HAVE_BUILTIN_COMPLEX
|
||||
# define CMPLX(x,y) __builtin_complex ((double) (x), (double) (y))
|
||||
#else
|
||||
static __inline double complex
|
||||
CMPLX(double x, double y)
|
||||
{
|
||||
double_complex z;
|
||||
|
||||
REALPART(z) = x;
|
||||
IMAGPART(z) = y;
|
||||
return (z.f);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CMPLXL
|
||||
#if HAVE_BUILTIN_COMPLEX
|
||||
# define CMPLXL(x,y) __builtin_complex ((long double) (x), (long double) (y))
|
||||
#else
|
||||
static __inline long double complex
|
||||
CMPLXL(long double x, long double y)
|
||||
{
|
||||
long_double_complex z;
|
||||
|
||||
REALPART(z) = x;
|
||||
IMAGPART(z) = y;
|
||||
return (z.f);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//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
|
||||
|
|
|
@ -23,6 +23,74 @@
|
|||
#define _Complex_I 1.0fi
|
||||
#define I _Complex_I
|
||||
|
||||
/*
|
||||
* Macros 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. Clang simply allows complex values to be constructed
|
||||
* using a compound literal.
|
||||
*
|
||||
* If __builtin_complex is not available, resort to using inline
|
||||
* functions instead. These can unfortunately not be used to construct
|
||||
* compile-time constants.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef __clang__
|
||||
# define CMPLXF(x, y) ((float complex){x, y})
|
||||
# define CMPLX(x, y) ((double complex){x, y})
|
||||
# define CMPLXL(x, y) ((long double complex){x, y})
|
||||
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__INTEL_COMPILER)
|
||||
# define CMPLXF(x,y) __builtin_complex ((float) (x), (float) (y))
|
||||
# define CMPLX(x,y) __builtin_complex ((double) (x), (double) (y))
|
||||
# define CMPLXL(x,y) __builtin_complex ((long double) (x), (long double) (y))
|
||||
#else
|
||||
static inline float complex
|
||||
CMPLXF(float x, float y)
|
||||
{
|
||||
union {
|
||||
float a[2];
|
||||
float complex f;
|
||||
} z = {{ x, y }};
|
||||
|
||||
return (z.f);
|
||||
}
|
||||
|
||||
static inline double complex
|
||||
CMPLX(double x, double y)
|
||||
{
|
||||
union {
|
||||
double a[2];
|
||||
double complex f;
|
||||
} z = {{ x, y }};
|
||||
|
||||
return (z.f);
|
||||
}
|
||||
|
||||
static inline long double complex
|
||||
CMPLXL(long double x, long double y)
|
||||
{
|
||||
union {
|
||||
long double a[2];
|
||||
long double complex f;
|
||||
} z = {{ x, y }};
|
||||
|
||||
return (z.f);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Double versions of C99 functions
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue