1 /* $OpenBSD: complex.h,v 1.5 2014/03/16 18:38:30 guenther Exp $ */ 2 /* 3 * Copyright (c) 2008 Martynas Venckus <martynas@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #ifdef OPENLIBM_USE_HOST_COMPLEX_H 19 #include <complex.h> 20 #else /* !OPENLIBM_USE_HOST_COMPLEX_H */ 21 22 #ifndef OPENLIBM_COMPLEX_H 23 #define OPENLIBM_COMPLEX_H 24 25 #define complex _Complex 26 27 #define _Complex_I 1.0fi 28 #define I _Complex_I 29 30 /* 31 * Macros that can be used to construct complex values. 32 * 33 * The C99 standard intends x+I*y to be used for this, but x+I*y is 34 * currently unusable in general since gcc introduces many overflow, 35 * underflow, sign and efficiency bugs by rewriting I*y as 36 * (0.0+I)*(y+0.0*I) and laboriously computing the full complex product. 37 * In particular, I*Inf is corrupted to NaN+I*Inf, and I*-0 is corrupted 38 * to -0.0+I*0.0. 39 * 40 * In C11, a CMPLX(x,y) macro was added to circumvent this limitation, 41 * and gcc 4.7 added a __builtin_complex feature to simplify implementation 42 * of CMPLX in libc, so we can take advantage of these features if they 43 * are available. Clang simply allows complex values to be constructed 44 * using a compound literal. 45 * 46 * If __builtin_complex is not available, resort to using inline 47 * functions instead. These can unfortunately not be used to construct 48 * compile-time constants. 49 * 50 * C99 specifies that complex numbers have the same representation as 51 * an array of two elements, where the first element is the real part 52 * and the second element is the imaginary part. 53 */ 54 55 #ifdef __clang__ 56 # define CMPLXF(x, y) ((float complex){x, y}) 57 # define CMPLX(x, y) ((double complex){x, y}) 58 # define CMPLXL(x, y) ((long double complex){x, y}) 59 #elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__INTEL_COMPILER) 60 # define CMPLXF(x,y) __builtin_complex ((float) (x), (float) (y)) 61 # define CMPLX(x,y) __builtin_complex ((double) (x), (double) (y)) 62 # define CMPLXL(x,y) __builtin_complex ((long double) (x), (long double) (y)) 63 #else 64 static inline float complex 65 CMPLXF(float x, float y) 66 { 67 union { 68 float a[2]; 69 float complex f; 70 } z = {{ x, y }}; 71 72 return (z.f); 73 } 74 75 static inline double complex 76 CMPLX(double x, double y) 77 { 78 union { 79 double a[2]; 80 double complex f; 81 } z = {{ x, y }}; 82 83 return (z.f); 84 } 85 86 static inline long double complex 87 CMPLXL(long double x, long double y) 88 { 89 union { 90 long double a[2]; 91 long double complex f; 92 } z = {{ x, y }}; 93 94 return (z.f); 95 } 96 #endif 97 98 /* 99 * Double versions of C99 functions 100 */ 101 double complex cacos(double complex); 102 double complex casin(double complex); 103 double complex catan(double complex); 104 double complex ccos(double complex); 105 double complex csin(double complex); 106 double complex ctan(double complex); 107 double complex cacosh(double complex); 108 double complex casinh(double complex); 109 double complex catanh(double complex); 110 double complex ccosh(double complex); 111 double complex csinh(double complex); 112 double complex ctanh(double complex); 113 double complex cexp(double complex); 114 double complex clog(double complex); 115 double cabs(double complex); 116 double complex cpow(double complex, double complex); 117 double complex csqrt(double complex); 118 double carg(double complex); 119 double cimag(double complex); 120 double complex conj(double complex); 121 double complex cproj(double complex); 122 double creal(double complex); 123 124 /* 125 * Float versions of C99 functions 126 */ 127 float complex cacosf(float complex); 128 float complex casinf(float complex); 129 float complex catanf(float complex); 130 float complex ccosf(float complex); 131 float complex csinf(float complex); 132 float complex ctanf(float complex); 133 float complex cacoshf(float complex); 134 float complex casinhf(float complex); 135 float complex catanhf(float complex); 136 float complex ccoshf(float complex); 137 float complex csinhf(float complex); 138 float complex ctanhf(float complex); 139 float complex cexpf(float complex); 140 float complex clogf(float complex); 141 float cabsf(float complex); 142 float complex cpowf(float complex, float complex); 143 float complex csqrtf(float complex); 144 float cargf(float complex); 145 float cimagf(float complex); 146 float complex conjf(float complex); 147 float complex cprojf(float complex); 148 float crealf(float complex); 149 150 /* 151 * Long double versions of C99 functions 152 */ 153 long double complex cacosl(long double complex); 154 long double complex casinl(long double complex); 155 long double complex catanl(long double complex); 156 long double complex ccosl(long double complex); 157 long double complex csinl(long double complex); 158 long double complex ctanl(long double complex); 159 long double complex cacoshl(long double complex); 160 long double complex casinhl(long double complex); 161 long double complex catanhl(long double complex); 162 long double complex ccoshl(long double complex); 163 long double complex csinhl(long double complex); 164 long double complex ctanhl(long double complex); 165 long double complex cexpl(long double complex); 166 long double complex clogl(long double complex); 167 long double cabsl(long double complex); 168 long double complex cpowl(long double complex, 169 long double complex); 170 long double complex csqrtl(long double complex); 171 long double cargl(long double complex); 172 long double cimagl(long double complex); 173 long double complex conjl(long double complex); 174 long double complex cprojl(long double complex); 175 long double creall(long double complex); 176 177 #endif /* !OPENLIBM_COMPLEX_H */ 178 179 #endif /* OPENLIBM_USE_HOST_COMPLEX_H */ 180