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.
This commit is contained in:
Danny Smith 2003-10-21 09:43:22 +00:00
parent 6de52354eb
commit 3c7a7a5fca
23 changed files with 766 additions and 2 deletions

View File

@ -1,3 +1,33 @@
2003-10-21 Danny Smith <dannysmith@users.sourceforge.net>
* 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.
2003-10-21 Danny Smith <dannysmith@users.sourceforge.net>
* include/math.h (cabs): Remove non-ISO prototype.

View File

@ -0,0 +1,109 @@
/*
* complex.h
*
* This file is part of the Mingw32 package.
*
* Contributors:
* Created by Danny Smith <dannysmith@users.sourceforge.net>
*
* THIS SOFTWARE IS NOT COPYRIGHTED
*
* This source code is offered for use in the public domain. You may
* use, modify or distribute it freely.
*
* This code is distributed in the hope that it will be useful but
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
* DISCLAIMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef _COMPLEX_H_
#define _COMPLEX_H_
/* All the headers include this file. */
#include <_mingw.h>
#if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \
|| !defined __STRICT_ANSI__
/* These macros are specified by C99 standard */
#ifndef __cplusplus
#define complex _Complex
#endif
#define _Complex_I (0.0F + 1.0iF)
/* GCC doesn't support _Imaginary type yet, so we don't
define _Imaginary_I */
#define I _Complex_I
#ifdef __cplusplus
extern "C" {
#endif
#ifndef RC_INVOKED
/* TODO: float and long double versions */
double __attribute__ ((const)) creal (double _Complex);
double __attribute__ ((const)) cimag (double _Complex);
double __attribute__ ((const)) carg (double _Complex);
double __attribute__ ((const)) cabs (double _Complex);
double _Complex __attribute__ ((const)) cconj (double _Complex);
double _Complex __attribute__ ((const)) cacos (double _Complex);
double _Complex __attribute__ ((const)) casin (double _Complex);
double _Complex __attribute__ ((const)) catan (double _Complex);
double _Complex __attribute__ ((const)) ccos (double _Complex);
double _Complex __attribute__ ((const)) csin (double _Complex);
double _Complex __attribute__ ((const)) ctan (double _Complex);
double _Complex __attribute__ ((const)) cacosh (double _Complex);
double _Complex __attribute__ ((const)) casinh (double _Complex);
double _Complex __attribute__ ((const)) catanh (double _Complex);
double _Complex __attribute__ ((const)) ccosh (double _Complex);
double _Complex __attribute__ ((const)) csinh (double _Complex);
double _Complex __attribute__ ((const)) ctanh (double _Complex);
double _Complex __attribute__ ((const)) cexp (double _Complex);
double _Complex __attribute__ ((const)) clog (double _Complex);
double _Complex __attribute__ ((const)) cpow (double _Complex, double _Complex);
double _Complex __attribute__ ((const)) csqrt (double _Complex);
double _Complex __attribute__ ((const)) cproj (double _Complex);
#ifdef __GNUC__
__CRT_INLINE double __attribute__ ((const)) creal (double _Complex _Z)
{
return __real__ _Z;
}
__CRT_INLINE double __attribute__ ((const)) cimag (double _Complex _Z)
{
return __imag__ _Z;
}
__CRT_INLINE double _Complex __attribute__ ((const)) conj (double _Complex _Z)
{
return __extension__ ~_Z;
}
__CRT_INLINE double __attribute__ ((const)) carg (double _Complex _Z)
{
double res;
__asm__ ("fpatan;"
: "=t" (res) : "0" (__real__ _Z), "u" (__imag__ _Z) : "st(1)");
return res;
}
#endif /* __GNUC__ */
#endif /* RC_INVOKED */
#ifdef __cplusplus
}
#endif
#endif /* __STDC_VERSION__ >= 199901L */
#endif /* _COMPLEX_H */

View File

@ -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

View File

@ -0,0 +1,7 @@
#include <math.h>
#include <complex.h>
double cabs (double complex Z)
{
return _hypot ( __real__ Z, __imag__ Z);
}

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -0,0 +1,6 @@
#include <complex.h>
double __attribute__ ((const)) cimag (double complex _Z)
{
return __imag__ _Z;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -0,0 +1,6 @@
#include <complex.h>
double __attribute__ ((const)) creal (double complex _Z)
{
return __real__ _Z;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}