diff options
author | Danny Smith <dannysmith@users.sourceforge.net> | 2003-10-21 13:43:22 +0400 |
---|---|---|
committer | Danny Smith <dannysmith@users.sourceforge.net> | 2003-10-21 13:43:22 +0400 |
commit | 3c7a7a5fcaaf92fc6762a23089738853973044d9 (patch) | |
tree | 4451bd7cfebc3022b0f780a5f0c40bd60db140c4 /winsup/mingw/mingwex | |
parent | 6de52354ebdfb6badf96e7825a09d832512e839d (diff) |
Add ISO C99 complex support for doubles.
* include/complex.h: New file.
* mingwex/complex: New directory.
* mingwex/complex/cabs.c: New file.
* mingwex/complex/cacos.c: New file.
* mingwex/complex/cacosh.c: New file.
* mingwex/complex/casin.c: New file.
* mingwex/complex/casinh.c: New file.
* mingwex/complex/catan.c: New file.
* mingwex/complex/catanh.c: New file.
* mingwex/complex/ccos.c: New file.
* mingwex/complex/ccosh.c: New file.
* mingwex/complex/cexp.c: New file.
* mingwex/complex/cimag.c: New file.
* mingwex/complex/clog.c: New file.
* mingwex/complex/cpow.c: New file.
* mingwex/complex/cproj.c: New file.
* mingwex/complex/creal.c: New file.
* mingwex/complex/csin.c: New file.
* mingwex/complex/csinh.c: New file.
* mingwex/complex/csqrt.c: New file.
* mingwex/complex/ctan.c: New file.
* mingwex/complex/ctanh.c: New file.
* mingwex/Makefile.in (COMPLEX_DISTFILES): New list of
files.
(dist): Use it.
(COMPLEX_OBJS): New list of objects.
(LIB_OBJS): Include it in the library.
Diffstat (limited to 'winsup/mingw/mingwex')
21 files changed, 627 insertions, 2 deletions
diff --git a/winsup/mingw/mingwex/Makefile.in b/winsup/mingw/mingwex/Makefile.in index dcd46c70f..cc9e44040 100644 --- a/winsup/mingw/mingwex/Makefile.in +++ b/winsup/mingw/mingwex/Makefile.in @@ -4,7 +4,7 @@ # This makefile requires GNU make. srcdir = @srcdir@ -VPATH = $(srcdir):$(srcdir)/math:$(srcdir)/stdio +VPATH = $(srcdir):$(srcdir)/math:$(srcdir)/stdio:$(srcdir)/complex objdir = . target_alias = @target_alias@ @@ -65,6 +65,11 @@ STDIO_DISTFILES = \ snprintf.c snwprintf.c vsnprintf.c vsnwprintf.c \ vfscanf.c vfwscanf.c vscanf.c vsscanf.c vswscanf.c vwscanf.c +COMPLEX_DISTFILES = \ + cabs.c cacos.c cacosh.c casin.c casinh.c catan.c catanh.c \ + ccos.c ccosh.c cexp.c cimag.c clog.c cpow.c cproj.c creal.c \ + csin.c csinh.c csqrt.c ctan.c ctanh.c + CC = @CC@ # FIXME: Which is it, CC or CC_FOR_TARGET? CC_FOR_TARGET = $(CC) @@ -143,10 +148,14 @@ POSIX_OBJS = \ dirent.o wdirent.o getopt.o REPLACE_OBJS = \ mingw-fseek.o +COMPLEX_OBJS = \ + cabs.o cacos.o cacosh.o casin.o casinh.o catan.o catanh.o \ + ccos.o ccosh.o cexp.o cimag.o clog.o cpow.o cproj.o creal.o \ + csin.o csinh.o csqrt.o ctan.o ctanh.o LIB_OBJS = $(Q8_OBJS) $(STDLIB_OBJS) $(STDLIB_STUB_OBJS) \ $(STDIO_OBJS) $(MATH_OBJS) $(FENV_OBJS) \ - $(POSIX_OBJS) $(REPLACE_OBJS) + $(POSIX_OBJS) $(REPLACE_OBJS) $(COMPLEX_OBJS) LIBS = $(LIBMINGWEX_A) DLLS = @@ -216,3 +225,9 @@ dist: @for i in $(STDIO_DISTFILES); do\ cp -p $(srcdir)/stdio/$$i $(distdir)/mingwex/stdio/$$i ; \ done + mkdir $(distdir)/mingwex/complex + chmod 755 $(distdir)/mingwex/complex + @for i in $(COMPLEX_DISTFILES); do\ + cp -p $(srcdir)/complex/$$i $(distdir)/mingwex/complex/$$i ; \ + done + diff --git a/winsup/mingw/mingwex/complex/cabs.c b/winsup/mingw/mingwex/complex/cabs.c new file mode 100644 index 000000000..ff547dd6e --- /dev/null +++ b/winsup/mingw/mingwex/complex/cabs.c @@ -0,0 +1,7 @@ +#include <math.h> +#include <complex.h> + +double cabs (double complex Z) +{ + return _hypot ( __real__ Z, __imag__ Z); +} diff --git a/winsup/mingw/mingwex/complex/cacos.c b/winsup/mingw/mingwex/complex/cacos.c new file mode 100644 index 000000000..265cba0d7 --- /dev/null +++ b/winsup/mingw/mingwex/complex/cacos.c @@ -0,0 +1,82 @@ +/* + cacos.c + Contributed by Danny Smith + 2003-10-20 +*/ + +#include <math.h> +#include <complex.h> + +#if 0 +/* cacos (Z) = -I * clog(Z + I * csqrt(1 - Z * Z)) */ + +double complex cacos (double complex Z) +{ + double complex Res; + double x, y; + + x = __real__ Z; + y = __imag__ Z; + + if (y == 0.0) + { + __real__ Res = acos (x); + __imag__ Res = 0.0; + } + + else + { + double complex ZZ; + /* Z * Z = ((x - y) * (x + y)) + (2.0 * x * y) * I */ + /* caculate 1 - Z * Z */ + __real__ ZZ = 1.0 - (x - y) * (x + y); + __imag__ ZZ = -2.0 * x * y; + + + Res = csqrt(ZZ); + + /* calculate ZZ + I * sqrt (ZZ) */ + + __real__ ZZ = x - __imag__ Res; + __imag__ ZZ = y + __real__ Res; + + ZZ = clog(ZZ); + + /* mult by -I */ + + __real__ Res = __imag__ ZZ; + __imag__ Res = - __real__ ZZ; + } + return Res; +} + +#else + +/* cacos ( Z ) = pi/2 - casin ( Z ) */ + +double complex cacos (double complex Z) +{ + double complex Res = casin (Z); + __real__ Res = M_PI_2 - __real__ Res; + __imag__ Res = - __imag__ Res; + return Res; +} +#endif + +#if 0 +#include <stdio.h> +int main() +{ + double z; + double complex bar = 0.7 + 1.2 * I; + double complex foo = cacos (bar); + + printf ("%.16e\t%.16e\n", __real__ foo, __imag__ foo); + + foo = cacos (bar); + printf ("%.16e\t%.16e\n", __real__ foo, __imag__ foo); + + return 1; +} +#endif + diff --git a/winsup/mingw/mingwex/complex/cacosh.c b/winsup/mingw/mingwex/complex/cacosh.c new file mode 100644 index 000000000..34469cb56 --- /dev/null +++ b/winsup/mingw/mingwex/complex/cacosh.c @@ -0,0 +1,37 @@ +/* + cacosh.c + Contributed by Danny Smith + 2003-10-20 +*/ + +#include <math.h> +#include <complex.h> + +#if 0 +/* cacosh (z) = I * cacos (z) */ +double complex cacosh (double complex Z) +{ + double complex Tmp; + double complex Res; + + Tmp = cacos (Z); + __real__ Res = -__imag__ Tmp; + __imag__ Res = __real__ Tmp; + return Res; +} + +#else + +/* cacosh (z) = I * cacos (z) = I * (pi/2 - casin (z)) */ + +double complex cacosh (double complex Z) +{ + double complex Tmp; + double complex Res; + + Tmp = casin (Z); + __real__ Res = __imag__ Tmp; + __imag__ Res = M_PI_2 - __real__ Tmp; + return Res; +} +#endif diff --git a/winsup/mingw/mingwex/complex/casin.c b/winsup/mingw/mingwex/complex/casin.c new file mode 100644 index 000000000..cd79767b5 --- /dev/null +++ b/winsup/mingw/mingwex/complex/casin.c @@ -0,0 +1,48 @@ +/* + casin.c + Contributed by Danny Smith + 2003-10-20 +*/ + +#include <math.h> +#include <complex.h> + +/* casin (Z ) = -I * clog(I * Z + csqrt (1.0 - Z * Z))) */ + +double complex casin (double complex Z) +{ + double complex Res; + double x, y; + + x = __real__ Z; + y = __imag__ Z; + + if (y == 0.0) + { + __real__ Res = asin (x); + __imag__ Res = 0.0; + } + else /* -I * clog(I * Z + csqrt(1.0 - Z * Z))) */ + { + double complex ZZ; + + /* Z * Z = ((x - y) * (x + y)) + (2.0 * x * y) * I */ + /* calculate 1 - Z * Z */ + __real__ ZZ = 1.0 - (x - y) * (x + y); + __imag__ ZZ = -2.0 * x * y; + ZZ = csqrt (ZZ); + + + /* add I * Z to ZZ */ + + __real__ ZZ -= y; + __imag__ ZZ += x; + + ZZ = clog (ZZ); + + /* mult by -I */ + __real__ Res = __imag__ ZZ; + __imag__ Res = - __real__ ZZ; + } + return (Res); +} diff --git a/winsup/mingw/mingwex/complex/casinh.c b/winsup/mingw/mingwex/complex/casinh.c new file mode 100644 index 000000000..a86c1d625 --- /dev/null +++ b/winsup/mingw/mingwex/complex/casinh.c @@ -0,0 +1,23 @@ +/* + casinh.c + Contributed by Danny Smith + 2003-10-20 +*/ + +#include <math.h> +#include <complex.h> + +/* casinh (z) = -I casin (I * z) */ + +double complex casinh (double complex Z) +{ + double complex Tmp; + double complex Res; + + __real__ Tmp = - __imag__ Z; + __imag__ Tmp = __real__ Z; + Tmp = casin (Tmp); + __real__ Res = __imag__ Tmp; + __imag__ Res = - __real__ Tmp; + return Res; +} diff --git a/winsup/mingw/mingwex/complex/catan.c b/winsup/mingw/mingwex/complex/catan.c new file mode 100644 index 000000000..eee1e8fa7 --- /dev/null +++ b/winsup/mingw/mingwex/complex/catan.c @@ -0,0 +1,49 @@ +/* catan.c */ + +/* + Contributed by Danny Smith + 2003-10-17 + + FIXME: This needs some serious numerical analysis. +*/ + +#include <math.h> +#include <complex.h> +#include <errno.h> + +/* catan (z) = -I/2 * clog ((I + z) / (I - z)) */ + +double complex +catan (double complex Z) +{ + double complex Res; + double complex Tmp; + double x = __real__ Z; + double y = __imag__ Z; + + if ( x == 0.0 && (1.0 - fabs (y)) == 0.0) + { + errno = ERANGE; + __real__ Res = HUGE_VAL; + __imag__ Res = HUGE_VAL; + } + else if (isinf (_hypot (x, y))) + { + __real__ Res = (x > 0 ? M_PI_2 : -M_PI_2); + __imag__ Res = 0.0; + } + else + { + __real__ Tmp = - x; + __imag__ Tmp = 1.0 - y; + + __real__ Res = x; + __imag__ Res = y + 1.0; + + Tmp = clog (Res/Tmp); + __real__ Res = - 0.5 * __imag__ Tmp; + __imag__ Res = 0.5 * __real__ Tmp; + } + + return Res; +} diff --git a/winsup/mingw/mingwex/complex/catanh.c b/winsup/mingw/mingwex/complex/catanh.c new file mode 100644 index 000000000..78f028014 --- /dev/null +++ b/winsup/mingw/mingwex/complex/catanh.c @@ -0,0 +1,23 @@ +/* catanh.c */ +/* + Contributed by Danny Smith + 2003-10-20 +*/ + +#include <math.h> +#include <complex.h> + +/* catanh (z) = -I * catan (I * z) */ + +double complex catanh (double complex Z) +{ + double complex Tmp; + double complex Res; + + __real__ Tmp = - __imag__ Z; + __imag__ Tmp = __real__ Z; + Tmp = catan (Tmp); + __real__ Res = __imag__ Tmp; + __imag__ Res = - __real__ Tmp; + return Res; +} diff --git a/winsup/mingw/mingwex/complex/ccos.c b/winsup/mingw/mingwex/complex/ccos.c new file mode 100644 index 000000000..ef5b5a70e --- /dev/null +++ b/winsup/mingw/mingwex/complex/ccos.c @@ -0,0 +1,20 @@ +/* + ccos.c + Contributed by Danny Smith + 2003-10-20 +*/ + +#include <math.h> +#include <complex.h> + +/* ccos (x + I * y) = cos (x) * cosh (y) + + I * (sin (x) * sinh (y)) */ + + +double complex ccos (double complex Z) +{ + double complex Res; + __real__ Res = cos (__real__ Z) * cosh ( __imag__ Z); + __imag__ Res = -sin (__real__ Z) * sinh ( __imag__ Z); + return Res; +} diff --git a/winsup/mingw/mingwex/complex/ccosh.c b/winsup/mingw/mingwex/complex/ccosh.c new file mode 100644 index 000000000..8d304fd0e --- /dev/null +++ b/winsup/mingw/mingwex/complex/ccosh.c @@ -0,0 +1,19 @@ +/* + ccosh.c + Contributed by Danny Smith + 2003-10-20 +*/ + +#include <math.h> +#include <complex.h> + +/* ccosh (x + I * y) = cosh (x) * cos (y) + + I * (sinh (x) * sin (y)) */ + +double complex ccosh (double complex Z) +{ + double complex Res; + __real__ Res = cosh (__real__ Z) * cos (__imag__ Z); + __imag__ Res = sinh (__real__ Z) * sin (__imag__ Z); + return Res; +} diff --git a/winsup/mingw/mingwex/complex/cexp.c b/winsup/mingw/mingwex/complex/cexp.c new file mode 100644 index 000000000..43ac9ab9e --- /dev/null +++ b/winsup/mingw/mingwex/complex/cexp.c @@ -0,0 +1,19 @@ +/* + cexp.c + Contributed by Danny Smith + 2003-10-20 +*/ + +#include <math.h> +#include <complex.h> + +/* cexp (x + I * y) = exp (x) * cos (y) + I * exp (x) * sin (y) */ + +double complex cexp (double complex Z) +{ + double complex Res; + long double rho = exp (__real__ Z); + __real__ Res = rho * cos(__imag__ Z); + __imag__ Res = rho * sin(__imag__ Z); + return Res; +} diff --git a/winsup/mingw/mingwex/complex/cimag.c b/winsup/mingw/mingwex/complex/cimag.c new file mode 100644 index 000000000..b6b32561c --- /dev/null +++ b/winsup/mingw/mingwex/complex/cimag.c @@ -0,0 +1,6 @@ +#include <complex.h> +double __attribute__ ((const)) cimag (double complex _Z) +{ + return __imag__ _Z; +} + diff --git a/winsup/mingw/mingwex/complex/clog.c b/winsup/mingw/mingwex/complex/clog.c new file mode 100644 index 000000000..57c51ebb0 --- /dev/null +++ b/winsup/mingw/mingwex/complex/clog.c @@ -0,0 +1,19 @@ +/* + clog.c + Contributed by Danny Smith + 2003-10-20 +*/ + +/* clog (x + I * y) = log (hypot (x, y)) + I * atan2 (y, x) */ + +#include <math.h> +#include <complex.h> + +double complex clog (double complex Z) +{ + double complex Res; + __real__ Res = log (_hypot (__real__ Z, __imag__ Z)); + __imag__ Res = carg (Z); + return Res; +} + diff --git a/winsup/mingw/mingwex/complex/cpow.c b/winsup/mingw/mingwex/complex/cpow.c new file mode 100644 index 000000000..c12b12fc0 --- /dev/null +++ b/winsup/mingw/mingwex/complex/cpow.c @@ -0,0 +1,48 @@ +/* cpow.c */ +/* + Contributed by Danny Smith + 2003-10-20 +*/ + +/* cpow(X, Y) = cexp(X * clog(Y)) */ + +#include <math.h> +#include <complex.h> + +/* Use dll version of pow */ +extern double (*_imp__pow) (double, double); +#define pow (*_imp__pow) + +double complex cpow (double complex X, double complex Y) +{ + double complex Res; + double i; + double r = hypot (__real__ X, __imag__ X); + if (r == 0.0) + { + __real__ Res = __imag__ Res = 0.0; + } + else + { + double rho; + double theta; + i = carg (X); + theta = i * __real__ Y; + + if (__imag__ Y == 0.0) + /* This gives slightly more accurate results in these cases. */ + rho = pow (r, __real__ Y); + else + { + r = log (r); + /* rearrangement of cexp(X * clog(Y)) */ + theta += r * __imag__ Y; + rho = exp (r * __real__ Y - i * __imag__ Y); + } + + __real__ Res = rho * cos (theta); + __imag__ Res = rho * sin (theta); + } + return Res; +} + diff --git a/winsup/mingw/mingwex/complex/cproj.c b/winsup/mingw/mingwex/complex/cproj.c new file mode 100644 index 000000000..cc7c48d0f --- /dev/null +++ b/winsup/mingw/mingwex/complex/cproj.c @@ -0,0 +1,22 @@ +/* + cproj.c + Contributed by Danny Smith + 2003-10-20 +*/ + +#include <math.h> +#include <complex.h> + +/* Return the value of the projection onto the Riemann sphere.*/ + +double complex cproj (double complex Z) +{ + complex double Res = Z; + if (isinf (__real__ Z) || isinf (__imag__ Z)) + { + __real__ Res = HUGE_VAL; + __imag__ Res = copysign (0.0, __imag__ Z); + } + return Res; +} + diff --git a/winsup/mingw/mingwex/complex/creal.c b/winsup/mingw/mingwex/complex/creal.c new file mode 100644 index 000000000..6905b7e2a --- /dev/null +++ b/winsup/mingw/mingwex/complex/creal.c @@ -0,0 +1,6 @@ +#include <complex.h> +double __attribute__ ((const)) creal (double complex _Z) +{ + return __real__ _Z; +} + diff --git a/winsup/mingw/mingwex/complex/csin.c b/winsup/mingw/mingwex/complex/csin.c new file mode 100644 index 000000000..37df8057e --- /dev/null +++ b/winsup/mingw/mingwex/complex/csin.c @@ -0,0 +1,21 @@ +/* csin.c */ + +/* + Contributed by Danny Smith + 2003-10-20 +*/ + +#include <math.h> +#include <complex.h> + +/* csin (x + I * y) = sin (x) * cosh (y) + + I * (cos (x) * sinh (y)) */ + +double complex csin (double complex Z) +{ + double complex Res; + __real__ Res = sin (__real__ Z) * cosh ( __imag__ Z); + __imag__ Res = cos (__real__ Z) * sinh ( __imag__ Z); + return Res; +} + diff --git a/winsup/mingw/mingwex/complex/csinh.c b/winsup/mingw/mingwex/complex/csinh.c new file mode 100644 index 000000000..4ee6cbe86 --- /dev/null +++ b/winsup/mingw/mingwex/complex/csinh.c @@ -0,0 +1,21 @@ +/* csinh.c */ +/* + Contributed by Danny Smith + 2003-10-20 +*/ + + +#include <math.h> +#include <complex.h> + +/* csinh (x + I * y) = sinh (x) * cos (y) + + I * (cosh (x) * sin (y)) */ + + +double complex csinh (double complex Z) +{ + double complex Res; + __real__ Res = sinh (__real__ Z) * cos (__imag__ Z); + __imag__ Res = cosh (__real__ Z) * sin (__imag__ Z); + return Res; +} diff --git a/winsup/mingw/mingwex/complex/csqrt.c b/winsup/mingw/mingwex/complex/csqrt.c new file mode 100644 index 000000000..3717939f4 --- /dev/null +++ b/winsup/mingw/mingwex/complex/csqrt.c @@ -0,0 +1,55 @@ +/* + csqrt.c + Contributed by Danny Smith + 2003-10-20 +*/ + +#include <math.h> +#include <complex.h> + +double complex csqrt (double complex Z) +{ + double complex Res; + double t; + double x = __real__ Z; + double y = __imag__ Z; + + if (y == 0.0) + { + if (x < 0.0) + { + __real__ Res = 0.0; + __imag__ Res = sqrt (-x); + } + else + { + __real__ Res = sqrt (x); + __imag__ Res = 0.0; + } + } + + else if (x == 0.0) + { + t = sqrt(0.5 * fabs (y)); + __real__ Res = y > 0 ? t : -t; + __imag__ Res = t; + } + + else + { + t = sqrt (2.0 * (_hypot (x, y) + fabs (x))); + if ( x > 0.0) + { + __real__ Res = 0.5 * t; + __imag__ Res = y / t; + } + else + { + __real__ Res = fabs ( y / t); + __imag__ Res = (y < 0.0 ? -0.5 : 0.5) * t; + } + } + + return Res; +} + diff --git a/winsup/mingw/mingwex/complex/ctan.c b/winsup/mingw/mingwex/complex/ctan.c new file mode 100644 index 000000000..a479772a9 --- /dev/null +++ b/winsup/mingw/mingwex/complex/ctan.c @@ -0,0 +1,41 @@ +/* ctan.c */ + +/* + Contributed by Danny Smith + 2003-10-20 +*/ + +#include <math.h> +#include <complex.h> +#include <errno.h> + + +/* ctan (x + I * y) = (sin (2 * x) + I * sinh(2 * y)) + / (cos (2 * x) + cosh (2 * y)) */ + +double complex ctan (double complex Z) +{ + double complex Res; + double two_I = 2.0 * __imag__ Z; + double two_R = 2.0 * __real__ Z; + double denom = cos (two_R) + cosh (two_I); + if (denom == 0.0) + { + errno = ERANGE; + __real__ Res = HUGE_VAL; + __imag__ Res = HUGE_VAL; + } + else if (isinf (denom)) + { + errno = ERANGE; + __real__ Res = 0.0; + __imag__ Res = two_I > 0 ? 1.0 : -1.0; + } + else + { + __real__ Res = sin (two_R) / denom; + __imag__ Res = sinh (two_I) / denom; + } + return Res; +} + diff --git a/winsup/mingw/mingwex/complex/ctanh.c b/winsup/mingw/mingwex/complex/ctanh.c new file mode 100644 index 000000000..6d3e615da --- /dev/null +++ b/winsup/mingw/mingwex/complex/ctanh.c @@ -0,0 +1,44 @@ +/* ctanh.c */ + +/* + Contributed by Danny Smith + 2003-10-20 +*/ + + +#include <math.h> +#include <complex.h> +#include <errno.h> + +/* + ctanh (x + I * y) = (sinh (2 * x) + sin (2 * y) * I ) + / (cosh (2 * x) + cos (2 * y)) . +*/ + +double complex +ctanh (double complex Z) +{ + double complex Res; + double two_R = 2.0 * __real__ Z; + double two_I = 2.0 * __imag__ Z; + double denom = cosh (two_R) + cos (two_I); + + if (denom == 0.0) + { + errno = ERANGE; + __real__ Res = HUGE_VAL; + __imag__ Res = HUGE_VAL; + } + else if ( isinf (denom)) + { + errno = ERANGE; + __real__ Res = two_R > 0 ? 1.0 : -1.0; + __imag__ Res = 0.0; + } + else + { + __real__ Res = sinh (two_R) / denom; + __imag__ Res = sin (two_I) / denom; + } + return Res; +} |