|
17 | 17 | #ifndef _MATH_H_ |
18 | 18 | #define _MATH_H_ |
19 | 19 |
|
| 20 | +#include <complex.h> |
20 | 21 | #include "cdefs-compat.h" |
21 | 22 | #include "types-compat.h" |
22 | 23 |
|
@@ -167,6 +168,86 @@ extern int signgam; |
167 | 168 | #endif |
168 | 169 | #endif /* __BSD_VISIBLE */ |
169 | 170 |
|
| 171 | +//VBS |
| 172 | +//#ifdef _COMPLEX_H |
| 173 | + |
| 174 | +/* |
| 175 | + * C99 specifies that complex numbers have the same representation as |
| 176 | + * an array of two elements, where the first element is the real part |
| 177 | + * and the second element is the imaginary part. |
| 178 | + */ |
| 179 | +typedef union { |
| 180 | + float complex f; |
| 181 | + float a[2]; |
| 182 | +} float_complex; |
| 183 | +typedef union { |
| 184 | + double complex f; |
| 185 | + double a[2]; |
| 186 | +} double_complex; |
| 187 | +typedef union { |
| 188 | + long double complex f; |
| 189 | + long double a[2]; |
| 190 | +} long_double_complex; |
| 191 | +#define REALPART(z) ((z).a[0]) |
| 192 | +#define IMAGPART(z) ((z).a[1]) |
| 193 | + |
| 194 | +/* |
| 195 | + * Inline functions that can be used to construct complex values. |
| 196 | + * |
| 197 | + * The C99 standard intends x+I*y to be used for this, but x+I*y is |
| 198 | + * currently unusable in general since gcc introduces many overflow, |
| 199 | + * underflow, sign and efficiency bugs by rewriting I*y as |
| 200 | + * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product. |
| 201 | + * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted |
| 202 | + * to -0.0+I*0.0. |
| 203 | + * |
| 204 | + * In C11, a CMPLX(x,y) macro was added to circumvent this limitation, |
| 205 | + * and gcc 4.7 added a __builtin_complex feature to simplify implementation |
| 206 | + * of CMPLX in libc, so we can take advantage of these features if they |
| 207 | + * are available. |
| 208 | + */ |
| 209 | +#if defined(CMPLXF) && defined(CMPLX) && defined(CMPLXL) /* C11 */ |
| 210 | +# define cpackf(x,y) CMPLXF(x,y) |
| 211 | +# define cpack(x,y) CMPLX(x,y) |
| 212 | +# define cpackl(x,y) CMPLXL(x,y) |
| 213 | +#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__INTEL_COMPILER) |
| 214 | +# define cpackf(x,y) __builtin_complex ((float) (x), (float) (y)) |
| 215 | +# define cpack(x,y) __builtin_complex ((double) (x), (double) (y)) |
| 216 | +# define cpackl(x,y) __builtin_complex ((long double) (x), (long double) (y)) |
| 217 | +#else /* define our own cpack functions */ |
| 218 | +static __inline float complex |
| 219 | +cpackf(float x, float y) |
| 220 | +{ |
| 221 | + float_complex z; |
| 222 | + |
| 223 | + REALPART(z) = x; |
| 224 | + IMAGPART(z) = y; |
| 225 | + return (z.f); |
| 226 | +} |
| 227 | + |
| 228 | +static __inline double complex |
| 229 | +cpack(double x, double y) |
| 230 | +{ |
| 231 | + double_complex z; |
| 232 | + |
| 233 | + REALPART(z) = x; |
| 234 | + IMAGPART(z) = y; |
| 235 | + return (z.f); |
| 236 | +} |
| 237 | + |
| 238 | +static __inline long double complex |
| 239 | +cpackl(long double x, long double y) |
| 240 | +{ |
| 241 | + long_double_complex z; |
| 242 | + |
| 243 | + REALPART(z) = x; |
| 244 | + IMAGPART(z) = y; |
| 245 | + return (z.f); |
| 246 | +} |
| 247 | +#endif /* define our own cpack functions */ |
| 248 | +//VBS |
| 249 | +//#endif /* _COMPLEX_H */ |
| 250 | + |
170 | 251 | /* |
171 | 252 | * Most of these functions depend on the rounding mode and have the side |
172 | 253 | * effect of raising floating-point exceptions, so they are not declared |
|
0 commit comments