diff --git a/winsup/mingw/ChangeLog b/winsup/mingw/ChangeLog index 92b3dc6ee..884a09a74 100644 --- a/winsup/mingw/ChangeLog +++ b/winsup/mingw/ChangeLog @@ -1,3 +1,16 @@ +2004-12-26 Danny Smith + + * mingwex/complex/(cabsf.c cacosf.c cacoshf.c cargf.c casinf.c + casinhf.c catanf.c catanhf.c ccosf.c ccoshf.c cexpf.c cimagf.c + clogf.c cpowf.c cprojf.c crealf.c csinf.c csinhf.c csqrtf.c + ctanf.c ctanhf.c): New files. + * mingwex/Makefile.in (COMPLEX_DISTFILES): Adjust. + (COMPLEX_OBJS(: Adjust. + * include/complex.h (cabsf, cacosf, cacoshf, cargf, casinf. + casinhf, catanf, catanhf, ccosf, ccoshf, cexpf, cimagf, clogf, + cpowf, cprojf, crealf, csinf, csinhf, csqrtf, ctanf, ctanhf): + Declare. + 2004-12-20 Danny Smith * include/wchar.h (wcsdup): Correct prototype. diff --git a/winsup/mingw/include/complex.h b/winsup/mingw/include/complex.h index 90e7903bd..3ab2c9e3a 100644 --- a/winsup/mingw/include/complex.h +++ b/winsup/mingw/include/complex.h @@ -46,7 +46,7 @@ extern "C" { #ifndef RC_INVOKED -/* TODO: float and long double versions */ +/* TODO: long double versions */ double __MINGW_ATTRIB_CONST creal (double _Complex); double __MINGW_ATTRIB_CONST cimag (double _Complex); double __MINGW_ATTRIB_CONST carg (double _Complex); @@ -70,6 +70,29 @@ double _Complex cpow (double _Complex, double _Complex); double _Complex csqrt (double _Complex); double _Complex __MINGW_ATTRIB_CONST cproj (double _Complex); +float __MINGW_ATTRIB_CONST crealf (float _Complex); +float __MINGW_ATTRIB_CONST cimagf (float _Complex); +float __MINGW_ATTRIB_CONST cargf (float _Complex); +float __MINGW_ATTRIB_CONST cabsf (float _Complex); +float _Complex __MINGW_ATTRIB_CONST conjf (float _Complex); +float _Complex cacosf (float _Complex); +float _Complex casinf (float _Complex); +float _Complex catanf (float _Complex); +float _Complex ccosf (float _Complex); +float _Complex csinf (float _Complex); +float _Complex ctanf (float _Complex); +float _Complex cacoshf (float _Complex); +float _Complex casinhf (float _Complex); +float _Complex catanhf (float _Complex); +float _Complex ccoshf (float _Complex); +float _Complex csinhf (float _Complex); +float _Complex ctanhf (float _Complex); +float _Complex cexpf (float _Complex); +float _Complex clogf (float _Complex); +float _Complex cpowf (float _Complex, float _Complex); +float _Complex csqrtf (float _Complex); +float _Complex __MINGW_ATTRIB_CONST cprojf (float _Complex); + #ifdef __GNUC__ __CRT_INLINE double __MINGW_ATTRIB_CONST creal (double _Complex _Z) @@ -94,6 +117,30 @@ __CRT_INLINE double __MINGW_ATTRIB_CONST carg (double _Complex _Z) : "=t" (res) : "0" (__real__ _Z), "u" (__imag__ _Z) : "st(1)"); return res; } + + +__CRT_INLINE float __MINGW_ATTRIB_CONST crealf (float _Complex _Z) +{ + return __real__ _Z; +} + +__CRT_INLINE float __MINGW_ATTRIB_CONST cimagf (float _Complex _Z) +{ + return __imag__ _Z; +} + +__CRT_INLINE float _Complex __MINGW_ATTRIB_CONST conjf (float _Complex _Z) +{ + return __extension__ ~_Z; +} + +__CRT_INLINE float __MINGW_ATTRIB_CONST cargf (float _Complex _Z) +{ + float res; + __asm__ ("fpatan;" + : "=t" (res) : "0" (__real__ _Z), "u" (__imag__ _Z) : "st(1)"); + return res; +} #endif /* __GNUC__ */ diff --git a/winsup/mingw/mingwex/Makefile.in b/winsup/mingw/mingwex/Makefile.in index 0dcf1ed3b..66659a63d 100644 --- a/winsup/mingw/mingwex/Makefile.in +++ b/winsup/mingw/mingwex/Makefile.in @@ -70,9 +70,12 @@ STDIO_DISTFILES = \ vfscanf.c vfwscanf.c vscanf.c vsscanf.c vswscanf.c vwscanf.c COMPLEX_DISTFILES = \ - cabs.c cacos.c cacosh.c carg.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 + cabs.c cabsf.c cacos.c cacosf.c cacosh.c cacoshf.c carg.c \ + cargf.c casin.c casinf.c casinh.c casinhf.c catan.c catanf.c \ + catanh.c catanhf.c ccos.c ccosf.c ccosh.c ccoshf.c cexp.c \ + cexpf.c cimag.c cimagf.c clog.c clogf.c cpow.c cpowf.c cproj.c \ + cprojf.c creal.c crealf.c csin.c csinf.c csinh.c csinhf.c \ + csqrt.c csqrtf.c ctan.c ctanf.c ctanh.c ctanhf.c CC = @CC@ # FIXME: Which is it, CC or CC_FOR_TARGET? @@ -156,9 +159,12 @@ POSIX_OBJS = \ REPLACE_OBJS = \ mingw-aligned-malloc.o mingw-fseek.o COMPLEX_OBJS = \ - cabs.o cacos.o cacosh.o carg.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 + cabs.o cabsf.o cacos.o cacosf.o cacosh.o cacoshf.o carg.o \ + cargf.o casin.o casinf.o casinh.o casinhf.o catan.o catanf.o \ + catanh.o catanhf.o ccos.o ccosf.o ccosh.o ccoshf.o cexp.o \ + cexpf.o cimag.o cimagf.o clog.o clogf.o cpow.o cpowf.o cproj.o \ + cprojf.o creal.o crealf.o csin.o csinf.o csinh.o csinhf.o \ + csqrt.o csqrtf.o ctan.o ctanf.o ctanh.o ctanhf.o LIB_OBJS = $(Q8_OBJS) $(STDLIB_OBJS) $(STDLIB_STUB_OBJS) \ $(STDIO_OBJS) $(MATH_OBJS) $(FENV_OBJS) \ diff --git a/winsup/mingw/mingwex/complex/cabsf.c b/winsup/mingw/mingwex/complex/cabsf.c new file mode 100755 index 000000000..452e88f1c --- /dev/null +++ b/winsup/mingw/mingwex/complex/cabsf.c @@ -0,0 +1,7 @@ +#include +#include + +float cabsf (float complex Z) +{ + return (float) _hypot ( __real__ Z, __imag__ Z); +} diff --git a/winsup/mingw/mingwex/complex/cacosf.c b/winsup/mingw/mingwex/complex/cacosf.c new file mode 100755 index 000000000..f2fbbd9b3 --- /dev/null +++ b/winsup/mingw/mingwex/complex/cacosf.c @@ -0,0 +1,64 @@ +/* + cacosf.c + Contributed by Danny Smith + 2004-12-24 +*/ + +#include +#include + +#if 0 +/* cacos (Z) = -I * clog(Z + I * csqrt(1 - Z * Z)) */ + +float complex cacos (float complex Z) +{ + float complex Res; + float x, y; + + x = __real__ Z; + y = __imag__ Z; + + if (y == 0.0f) + { + __real__ Res = acosf (x); + __imag__ Res = 0.0f; + } + + else + { + float complex ZZ; + /* Z * Z = ((x - y) * (x + y)) + (2.0 * x * y) * I */ + /* caculate 1 - Z * Z */ + __real__ ZZ = 1.0f - (x - y) * (x + y); + __imag__ ZZ = -2.0f * x * y; + + + Res = csqrtf(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 ) */ + +float complex cacosf (float complex Z) +{ + float complex Res = casinf (Z); + __real__ Res = M_PI_2 - __real__ Res; + __imag__ Res = - __imag__ Res; + return Res; +} +#endif diff --git a/winsup/mingw/mingwex/complex/cacoshf.c b/winsup/mingw/mingwex/complex/cacoshf.c new file mode 100755 index 000000000..411afb3c5 --- /dev/null +++ b/winsup/mingw/mingwex/complex/cacoshf.c @@ -0,0 +1,37 @@ +/* + cacoshf.c + Contributed by Danny Smith + 2004-12-24 +*/ + +#include +#include + +#if 0 +/* cacoshf (z) = I * cacos (z) */ +float complex cacosh (float complex Z) +{ + float complex Tmp; + float complex Res; + + Tmp = cacosf (Z); + __real__ Res = -__imag__ Tmp; + __imag__ Res = __real__ Tmp; + return Res; +} + +#else + +/* cacosh (z) = I * cacos (z) = I * (pi/2 - casin (z)) */ + +float complex cacoshf (float complex Z) +{ + float complex Tmp; + float complex Res; + + Tmp = casinf (Z); + __real__ Res = __imag__ Tmp; + __imag__ Res = M_PI_2 - __real__ Tmp; + return Res; +} +#endif diff --git a/winsup/mingw/mingwex/complex/cargf.c b/winsup/mingw/mingwex/complex/cargf.c new file mode 100755 index 000000000..360beefe4 --- /dev/null +++ b/winsup/mingw/mingwex/complex/cargf.c @@ -0,0 +1,9 @@ +#include +float __attribute__ ((const)) cargf (float _Complex _Z) +{ + float res; + __asm__ ("fpatan;" + : "=t" (res) : "0" (__real__ _Z), "u" (__imag__ _Z) : "st(1)"); + return res; +} + diff --git a/winsup/mingw/mingwex/complex/casinf.c b/winsup/mingw/mingwex/complex/casinf.c new file mode 100755 index 000000000..a70058b0c --- /dev/null +++ b/winsup/mingw/mingwex/complex/casinf.c @@ -0,0 +1,48 @@ +/* + casinf.c + Contributed by Danny Smith + 2004-12-24 +*/ + +#include +#include + +/* casin (Z ) = -I * clog(I * Z + csqrt (1.0 - Z * Z))) */ + +float complex casinf (float complex Z) +{ + float complex Res; + float x, y; + + x = __real__ Z; + y = __imag__ Z; + + if (y == 0.0f) + { + __real__ Res = asinf (x); + __imag__ Res = 0.0f; + } + else /* -I * clog(I * Z + csqrt(1.0 - Z * Z))) */ + { + float complex ZZ; + + /* Z * Z = ((x - y) * (x + y)) + (2.0 * x * y) * I */ + /* calculate 1 - Z * Z */ + __real__ ZZ = 1.0f - (x - y) * (x + y); + __imag__ ZZ = -2.0f * x * y; + ZZ = csqrtf (ZZ); + + + /* add I * Z to ZZ */ + + __real__ ZZ -= y; + __imag__ ZZ += x; + + ZZ = clogf (ZZ); + + /* mult by -I */ + __real__ Res = __imag__ ZZ; + __imag__ Res = - __real__ ZZ; + } + return (Res); +} diff --git a/winsup/mingw/mingwex/complex/casinhf.c b/winsup/mingw/mingwex/complex/casinhf.c new file mode 100755 index 000000000..421cd3a96 --- /dev/null +++ b/winsup/mingw/mingwex/complex/casinhf.c @@ -0,0 +1,23 @@ +/* + casinhf.c + Contributed by Danny Smith + 2004-12-24 +*/ + +#include +#include + +/* casinh (z) = -I casin (I * z) */ + +float complex casinhf (float complex Z) +{ + float complex Tmp; + float complex Res; + + __real__ Tmp = - __imag__ Z; + __imag__ Tmp = __real__ Z; + Tmp = casinf (Tmp); + __real__ Res = __imag__ Tmp; + __imag__ Res = - __real__ Tmp; + return Res; +} diff --git a/winsup/mingw/mingwex/complex/catanf.c b/winsup/mingw/mingwex/complex/catanf.c new file mode 100755 index 000000000..adddde885 --- /dev/null +++ b/winsup/mingw/mingwex/complex/catanf.c @@ -0,0 +1,49 @@ +/* catanf.c */ + +/* + Contributed by Danny Smith + 2004-12-24 + + FIXME: This needs some serious numerical analysis. +*/ + +#include +#include +#include + +/* catan (z) = -I/2 * clog ((I + z) / (I - z)) */ + +float complex +catanf (float complex Z) +{ + float complex Res; + float complex Tmp; + float x = __real__ Z; + float y = __imag__ Z; + + if ( x == 0.0f && (1.0f - fabsf (y)) == 0.0f) + { + errno = ERANGE; + __real__ Res = HUGE_VALF; + __imag__ Res = HUGE_VALF; + } + else if (isinf (hypotf (x, y))) + { + __real__ Res = (x > 0 ? M_PI_2 : -M_PI_2); + __imag__ Res = 0.0f; + } + else + { + __real__ Tmp = - x; + __imag__ Tmp = 1.0f - y; + + __real__ Res = x; + __imag__ Res = y + 1.0f; + + Tmp = clogf (Res/Tmp); + __real__ Res = - 0.5f * __imag__ Tmp; + __imag__ Res = 0.5f * __real__ Tmp; + } + + return Res; +} diff --git a/winsup/mingw/mingwex/complex/catanhf.c b/winsup/mingw/mingwex/complex/catanhf.c new file mode 100755 index 000000000..7a792e88b --- /dev/null +++ b/winsup/mingw/mingwex/complex/catanhf.c @@ -0,0 +1,23 @@ +/* catanhf.c */ +/* + Contributed by Danny Smith + 2004-12-24 +*/ + +#include +#include + +/* catanh (z) = -I * catan (I * z) */ + +float complex catanhf (float complex Z) +{ + float complex Tmp; + float complex Res; + + __real__ Tmp = - __imag__ Z; + __imag__ Tmp = __real__ Z; + Tmp = catanf (Tmp); + __real__ Res = __imag__ Tmp; + __imag__ Res = - __real__ Tmp; + return Res; +} diff --git a/winsup/mingw/mingwex/complex/ccosf.c b/winsup/mingw/mingwex/complex/ccosf.c new file mode 100755 index 000000000..64a676455 --- /dev/null +++ b/winsup/mingw/mingwex/complex/ccosf.c @@ -0,0 +1,20 @@ +/* + ccosf.c + Contributed by Danny Smith + 2003-12-24 +*/ + +#include +#include + +/* ccos (x + I * y) = cos (x) * cosh (y) + + I * (sin (x) * sinh (y)) */ + + +float complex ccosf (float complex Z) +{ + float complex Res; + __real__ Res = cosf (__real__ Z) * coshf ( __imag__ Z); + __imag__ Res = -sinf (__real__ Z) * sinhf ( __imag__ Z); + return Res; +} diff --git a/winsup/mingw/mingwex/complex/ccoshf.c b/winsup/mingw/mingwex/complex/ccoshf.c new file mode 100755 index 000000000..ce78cd62d --- /dev/null +++ b/winsup/mingw/mingwex/complex/ccoshf.c @@ -0,0 +1,19 @@ +/* + ccoshf.c + Contributed by Danny Smith + 2004-12-24 +*/ + +#include +#include + +/* ccosh (x + I * y) = cosh (x) * cos (y) + + I * (sinh (x) * sin (y)) */ + +float complex ccoshf (float complex Z) +{ + float complex Res; + __real__ Res = coshf (__real__ Z) * cosf (__imag__ Z); + __imag__ Res = sinhf (__real__ Z) * sinf (__imag__ Z); + return Res; +} diff --git a/winsup/mingw/mingwex/complex/cexpf.c b/winsup/mingw/mingwex/complex/cexpf.c new file mode 100755 index 000000000..fabb1a0cb --- /dev/null +++ b/winsup/mingw/mingwex/complex/cexpf.c @@ -0,0 +1,19 @@ +/* + cexpf.c + Contributed by Danny Smith + 2004-12-24 +*/ + +#include +#include + +/* cexp (x + I * y) = exp (x) * cos (y) + I * exp (x) * sin (y) */ + +float complex cexpf (float complex Z) +{ + float complex Res; + double rho = exp (__real__ Z); + __real__ Res = rho * cosf(__imag__ Z); + __imag__ Res = rho * sinf(__imag__ Z); + return Res; +} diff --git a/winsup/mingw/mingwex/complex/cimagf.c b/winsup/mingw/mingwex/complex/cimagf.c new file mode 100755 index 000000000..f77b9ec54 --- /dev/null +++ b/winsup/mingw/mingwex/complex/cimagf.c @@ -0,0 +1,6 @@ +#include +float __attribute__ ((const)) cimagf (float complex _Z) +{ + return __imag__ _Z; +} + diff --git a/winsup/mingw/mingwex/complex/clogf.c b/winsup/mingw/mingwex/complex/clogf.c new file mode 100755 index 000000000..ead76025f --- /dev/null +++ b/winsup/mingw/mingwex/complex/clogf.c @@ -0,0 +1,19 @@ +/* + clogf.c + Contributed by Danny Smith + 2004-12-24 +*/ + +/* clog (x + I * y) = log (hypot (x, y)) + I * atan2 (y, x) */ + +#include +#include + +float complex clogf (float complex Z) +{ + float complex Res; + __real__ Res = logf (_hypot (__real__ Z, __imag__ Z)); + __imag__ Res = cargf (Z); + return Res; +} + diff --git a/winsup/mingw/mingwex/complex/cpowf.c b/winsup/mingw/mingwex/complex/cpowf.c new file mode 100755 index 000000000..eeeed1b7f --- /dev/null +++ b/winsup/mingw/mingwex/complex/cpowf.c @@ -0,0 +1,43 @@ +/* cpowf.c */ +/* + Contributed by Danny Smith + 2004-12-24 +*/ + +/* cpow(X, Y) = cexp(X * clog(Y)) */ + +#include +#include + +float complex cpowf (float complex X, float complex Y) +{ + float complex Res; + float i; + float r = _hypot (__real__ X, __imag__ X); + if (r == 0.0f) + { + __real__ Res = __imag__ Res = 0.0; + } + else + { + float rho; + float theta; + i = cargf (X); + theta = i * __real__ Y; + + if (__imag__ Y == 0.0f) + /* This gives slightly more accurate results in these cases. */ + rho = powf (r, __real__ Y); + else + { + r = logf (r); + /* rearrangement of cexp(X * clog(Y)) */ + theta += r * __imag__ Y; + rho = expf (r * __real__ Y - i * __imag__ Y); + } + + __real__ Res = rho * cosf (theta); + __imag__ Res = rho * sinf (theta); + } + return Res; +} diff --git a/winsup/mingw/mingwex/complex/cprojf.c b/winsup/mingw/mingwex/complex/cprojf.c new file mode 100755 index 000000000..f1d2d730a --- /dev/null +++ b/winsup/mingw/mingwex/complex/cprojf.c @@ -0,0 +1,22 @@ +/* + cprojf.c + Contributed by Danny Smith + 2004-12-24 +*/ + +#include +#include + +/* Return the value of the projection onto the Riemann sphere.*/ + +float complex cprojf (float complex Z) +{ + complex float Res = Z; + if (isinf (__real__ Z) || isinf (__imag__ Z)) + { + __real__ Res = HUGE_VALF; + __imag__ Res = copysignf (0.0f, __imag__ Z); + } + return Res; +} + diff --git a/winsup/mingw/mingwex/complex/crealf.c b/winsup/mingw/mingwex/complex/crealf.c new file mode 100755 index 000000000..16dc7ec46 --- /dev/null +++ b/winsup/mingw/mingwex/complex/crealf.c @@ -0,0 +1,6 @@ +#include +float __attribute__ ((const)) crealf (float complex _Z) +{ + return __real__ _Z; +} + diff --git a/winsup/mingw/mingwex/complex/csinf.c b/winsup/mingw/mingwex/complex/csinf.c new file mode 100755 index 000000000..def23f27e --- /dev/null +++ b/winsup/mingw/mingwex/complex/csinf.c @@ -0,0 +1,21 @@ +/* csinf.c */ + +/* + Contributed by Danny Smith + 2004-12-24 +*/ + +#include +#include + +/* csin (x + I * y) = sin (x) * cosh (y) + + I * (cos (x) * sinh (y)) */ + +float complex csinf (float complex Z) +{ + float complex Res; + __real__ Res = sinf (__real__ Z) * coshf ( __imag__ Z); + __imag__ Res = cosf (__real__ Z) * sinhf ( __imag__ Z); + return Res; +} + diff --git a/winsup/mingw/mingwex/complex/csinhf.c b/winsup/mingw/mingwex/complex/csinhf.c new file mode 100755 index 000000000..b0d008ed7 --- /dev/null +++ b/winsup/mingw/mingwex/complex/csinhf.c @@ -0,0 +1,21 @@ +/* csinhf.c */ +/* + Contributed by Danny Smith + 2004-12-24 +*/ + + +#include +#include + +/* csinh (x + I * y) = sinh (x) * cos (y) + + I * (cosh (x) * sin (y)) */ + + +float complex csinhf (float complex Z) +{ + float complex Res; + __real__ Res = sinhf (__real__ Z) * cosf (__imag__ Z); + __imag__ Res = coshf (__real__ Z) * sinf (__imag__ Z); + return Res; +} diff --git a/winsup/mingw/mingwex/complex/csqrtf.c b/winsup/mingw/mingwex/complex/csqrtf.c new file mode 100755 index 000000000..b39cbb468 --- /dev/null +++ b/winsup/mingw/mingwex/complex/csqrtf.c @@ -0,0 +1,49 @@ +#include +#include + +float complex csqrtf (float complex Z) +{ + float complex Res; + float r; + float x = __real__ Z; + float y = __imag__ Z; + + if (y == 0.0f) + { + if (x < 0.0f) + { + __real__ Res = 0.0f; + __imag__ Res = sqrtf (-x); + } + else + { + __real__ Res = sqrtf (x); + __imag__ Res = 0.0f; + } + } + + else if (x == 0.0f) + { + r = sqrtf(0.5f * fabsf (y)); + __real__ Res = y > 0 ? r : -r; + __imag__ Res = r; + } + + else + { + float t = sqrtf (2 * (_hypot (__real__ Z, __imag__ Z) + fabsf (x))); + float u = t / 2.0f; + if ( x > 0.0f) + { + __real__ Res = u; + __imag__ Res = y / t; + } + else + { + __real__ Res = fabsf (y / t); + __imag__ Res = y < 0 ? -u : u; + } + } + + return Res; +} diff --git a/winsup/mingw/mingwex/complex/ctanf.c b/winsup/mingw/mingwex/complex/ctanf.c new file mode 100755 index 000000000..99699e427 --- /dev/null +++ b/winsup/mingw/mingwex/complex/ctanf.c @@ -0,0 +1,41 @@ +/* ctanf.c */ + +/* + Contributed by Danny Smith + 2004-12-24 +*/ + +#include +#include +#include + + +/* ctan (x + I * y) = (sin (2 * x) + I * sinh(2 * y)) + / (cos (2 * x) + cosh (2 * y)) */ + +float complex ctanf (float complex Z) +{ + float complex Res; + float two_I = 2.0f * __imag__ Z; + float two_R = 2.0f * __real__ Z; + float denom = cosf (two_R) + coshf (two_I); + if (denom == 0.0f) + { + errno = ERANGE; + __real__ Res = HUGE_VALF; + __imag__ Res = HUGE_VALF; + } + else if (isinf (denom)) + { + errno = ERANGE; + __real__ Res = 0.0; + __imag__ Res = two_I > 0 ? 1.0f : -1.0f; + } + else + { + __real__ Res = sinf (two_R) / denom; + __imag__ Res = sinhf (two_I) / denom; + } + return Res; +} + diff --git a/winsup/mingw/mingwex/complex/ctanhf.c b/winsup/mingw/mingwex/complex/ctanhf.c new file mode 100755 index 000000000..82a9c9a43 --- /dev/null +++ b/winsup/mingw/mingwex/complex/ctanhf.c @@ -0,0 +1,44 @@ +/* ctanhf.c */ + +/* + Contributed by Danny Smith + 2004-12-24 +*/ + + +#include +#include +#include + +/* + ctanh (x + I * y) = (sinh (2 * x) + sin (2 * y) * I ) + / (cosh (2 * x) + cos (2 * y)) . +*/ + +float complex +ctanhf (float complex Z) +{ + float complex Res; + float two_R = 2.0f * __real__ Z; + float two_I = 2.0f * __imag__ Z; + float denom = coshf (two_R) + cosf (two_I); + + if (denom == 0.0f) + { + errno = ERANGE; + __real__ Res = HUGE_VALF; + __imag__ Res = HUGE_VALF; + } + else if (isinf (denom)) + { + errno = ERANGE; + __real__ Res = two_R > 0 ? 1.0f : -1.0f; + __imag__ Res = 0.0f; + } + else + { + __real__ Res = sinhf (two_R) / denom; + __imag__ Res = sinf (two_I) / denom; + } + return Res; +}