* ChangeLog: Add missing entries to last entry.
[official-gcc.git] / libgfortran / intrinsics / c99_functions.c
blobe26be0ecdb93a8278a68e993bbdadeef64fdec69
1 /* Implementation of various C99 functions
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This file is part of the GNU Fortran 95 runtime library (libgfortran).
6 Libgfortran is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 In addition to the permissions in the GNU General Public License, the
12 Free Software Foundation gives you unlimited permission to link the
13 compiled version of this file into combinations with other programs,
14 and to distribute those combinations without any restriction coming
15 from the use of this file. (The General Public License restrictions
16 do apply in other respects; for example, they cover modification of
17 the file, and distribution when not linked into a combine
18 executable.)
20 Libgfortran is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
25 You should have received a copy of the GNU General Public
26 License along with libgfortran; see the file COPYING. If not,
27 write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
28 Boston, MA 02110-1301, USA. */
30 #include "config.h"
31 #include <sys/types.h>
32 #include <float.h>
33 #include <math.h>
35 #define C99_PROTOS_H WE_DONT_WANT_PROTOS_NOW
36 #include "libgfortran.h"
38 /* IRIX's <math.h> declares a non-C99 compliant implementation of cabs,
39 which takes two floating point arguments instead of a single complex.
40 If <complex.h> is missing this prevents building of c99_functions.c.
41 To work around this we redirect cabs{,f,l} calls to __gfc_cabs{,f,l}. */
43 #if defined(__sgi__) && !defined(HAVE_COMPLEX_H)
44 #undef HAVE_CABS
45 #undef HAVE_CABSF
46 #undef HAVE_CABSL
47 #define cabs __gfc_cabs
48 #define cabsf __gfc_cabsf
49 #define cabsl __gfc_cabsl
50 #endif
52 /* Tru64's <math.h> declares a non-C99 compliant implementation of cabs,
53 which takes two floating point arguments instead of a single complex.
54 To work around this we redirect cabs{,f,l} calls to __gfc_cabs{,f,l}. */
56 #ifdef __osf__
57 #undef HAVE_CABS
58 #undef HAVE_CABSF
59 #undef HAVE_CABSL
60 #define cabs __gfc_cabs
61 #define cabsf __gfc_cabsf
62 #define cabsl __gfc_cabsl
63 #endif
65 /* Prototypes to silence -Wstrict-prototypes -Wmissing-prototypes. */
67 float cabsf(float complex);
68 double cabs(double complex);
69 long double cabsl(long double complex);
71 float cargf(float complex);
72 double carg(double complex);
73 long double cargl(long double complex);
75 float complex clog10f(float complex);
76 double complex clog10(double complex);
77 long double complex clog10l(long double complex);
80 #ifndef HAVE_ACOSF
81 #define HAVE_ACOSF 1
82 float
83 acosf(float x)
85 return (float) acos(x);
87 #endif
89 #ifndef HAVE_ASINF
90 #define HAVE_ASINF 1
91 float
92 asinf(float x)
94 return (float) asin(x);
96 #endif
98 #ifndef HAVE_ATAN2F
99 #define HAVE_ATAN2F 1
100 float
101 atan2f(float y, float x)
103 return (float) atan2(y, x);
105 #endif
107 #ifndef HAVE_ATANF
108 #define HAVE_ATANF 1
109 float
110 atanf(float x)
112 return (float) atan(x);
114 #endif
116 #ifndef HAVE_CEILF
117 #define HAVE_CEILF 1
118 float
119 ceilf(float x)
121 return (float) ceil(x);
123 #endif
125 #ifndef HAVE_COPYSIGNF
126 #define HAVE_COPYSIGNF 1
127 float
128 copysignf(float x, float y)
130 return (float) copysign(x, y);
132 #endif
134 #ifndef HAVE_COSF
135 #define HAVE_COSF 1
136 float
137 cosf(float x)
139 return (float) cos(x);
141 #endif
143 #ifndef HAVE_COSHF
144 #define HAVE_COSHF 1
145 float
146 coshf(float x)
148 return (float) cosh(x);
150 #endif
152 #ifndef HAVE_EXPF
153 #define HAVE_EXPF 1
154 float
155 expf(float x)
157 return (float) exp(x);
159 #endif
161 #ifndef HAVE_FABSF
162 #define HAVE_FABSF 1
163 float
164 fabsf(float x)
166 return (float) fabs(x);
168 #endif
170 #ifndef HAVE_FLOORF
171 #define HAVE_FLOORF 1
172 float
173 floorf(float x)
175 return (float) floor(x);
177 #endif
179 #ifndef HAVE_FREXPF
180 #define HAVE_FREXPF 1
181 float
182 frexpf(float x, int *exp)
184 return (float) frexp(x, exp);
186 #endif
188 #ifndef HAVE_HYPOTF
189 #define HAVE_HYPOTF 1
190 float
191 hypotf(float x, float y)
193 return (float) hypot(x, y);
195 #endif
197 #ifndef HAVE_LOGF
198 #define HAVE_LOGF 1
199 float
200 logf(float x)
202 return (float) log(x);
204 #endif
206 #ifndef HAVE_LOG10F
207 #define HAVE_LOG10F 1
208 float
209 log10f(float x)
211 return (float) log10(x);
213 #endif
215 #ifndef HAVE_SCALBN
216 #define HAVE_SCALBN 1
217 double
218 scalbn(double x, int y)
220 return x * pow(FLT_RADIX, y);
222 #endif
224 #ifndef HAVE_SCALBNF
225 #define HAVE_SCALBNF 1
226 float
227 scalbnf(float x, int y)
229 return (float) scalbn(x, y);
231 #endif
233 #ifndef HAVE_SINF
234 #define HAVE_SINF 1
235 float
236 sinf(float x)
238 return (float) sin(x);
240 #endif
242 #ifndef HAVE_SINHF
243 #define HAVE_SINHF 1
244 float
245 sinhf(float x)
247 return (float) sinh(x);
249 #endif
251 #ifndef HAVE_SQRTF
252 #define HAVE_SQRTF 1
253 float
254 sqrtf(float x)
256 return (float) sqrt(x);
258 #endif
260 #ifndef HAVE_TANF
261 #define HAVE_TANF 1
262 float
263 tanf(float x)
265 return (float) tan(x);
267 #endif
269 #ifndef HAVE_TANHF
270 #define HAVE_TANHF 1
271 float
272 tanhf(float x)
274 return (float) tanh(x);
276 #endif
278 #ifndef HAVE_TRUNC
279 #define HAVE_TRUNC 1
280 double
281 trunc(double x)
283 if (!isfinite (x))
284 return x;
286 if (x < 0.0)
287 return - floor (-x);
288 else
289 return floor (x);
291 #endif
293 #ifndef HAVE_TRUNCF
294 #define HAVE_TRUNCF 1
295 float
296 truncf(float x)
298 return (float) trunc (x);
300 #endif
302 #ifndef HAVE_NEXTAFTERF
303 #define HAVE_NEXTAFTERF 1
304 /* This is a portable implementation of nextafterf that is intended to be
305 independent of the floating point format or its in memory representation.
306 This implementation works correctly with denormalized values. */
307 float
308 nextafterf(float x, float y)
310 /* This variable is marked volatile to avoid excess precision problems
311 on some platforms, including IA-32. */
312 volatile float delta;
313 float absx, denorm_min;
315 if (isnan(x) || isnan(y))
316 return x + y;
317 if (x == y)
318 return x;
319 if (!isfinite (x))
320 return x > 0 ? __FLT_MAX__ : - __FLT_MAX__;
322 /* absx = fabsf (x); */
323 absx = (x < 0.0) ? -x : x;
325 /* __FLT_DENORM_MIN__ is non-zero iff the target supports denormals. */
326 if (__FLT_DENORM_MIN__ == 0.0f)
327 denorm_min = __FLT_MIN__;
328 else
329 denorm_min = __FLT_DENORM_MIN__;
331 if (absx < __FLT_MIN__)
332 delta = denorm_min;
333 else
335 float frac;
336 int exp;
338 /* Discard the fraction from x. */
339 frac = frexpf (absx, &exp);
340 delta = scalbnf (0.5f, exp);
342 /* Scale x by the epsilon of the representation. By rights we should
343 have been able to combine this with scalbnf, but some targets don't
344 get that correct with denormals. */
345 delta *= __FLT_EPSILON__;
347 /* If we're going to be reducing the absolute value of X, and doing so
348 would reduce the exponent of X, then the delta to be applied is
349 one exponent smaller. */
350 if (frac == 0.5f && (y < x) == (x > 0))
351 delta *= 0.5f;
353 /* If that underflows to zero, then we're back to the minimum. */
354 if (delta == 0.0f)
355 delta = denorm_min;
358 if (y < x)
359 delta = -delta;
361 return x + delta;
363 #endif
366 #ifndef HAVE_POWF
367 #define HAVE_POWF 1
368 float
369 powf(float x, float y)
371 return (float) pow(x, y);
373 #endif
375 /* Note that if fpclassify is not defined, then NaN is not handled */
377 /* Algorithm by Steven G. Kargl. */
379 #ifndef HAVE_ROUND
380 #define HAVE_ROUND 1
381 /* Round to nearest integral value. If the argument is halfway between two
382 integral values then round away from zero. */
384 double
385 round(double x)
387 double t;
388 if (!isfinite (x))
389 return (x);
391 if (x >= 0.0)
393 t = ceil(x);
394 if (t - x > 0.5)
395 t -= 1.0;
396 return (t);
398 else
400 t = ceil(-x);
401 if (t + x > 0.5)
402 t -= 1.0;
403 return (-t);
406 #endif
408 #ifndef HAVE_ROUNDF
409 #define HAVE_ROUNDF 1
410 /* Round to nearest integral value. If the argument is halfway between two
411 integral values then round away from zero. */
413 float
414 roundf(float x)
416 float t;
417 if (!isfinite (x))
418 return (x);
420 if (x >= 0.0)
422 t = ceilf(x);
423 if (t - x > 0.5)
424 t -= 1.0;
425 return (t);
427 else
429 t = ceilf(-x);
430 if (t + x > 0.5)
431 t -= 1.0;
432 return (-t);
435 #endif
437 #ifndef HAVE_LOG10L
438 #define HAVE_LOG10L 1
439 /* log10 function for long double variables. The version provided here
440 reduces the argument until it fits into a double, then use log10. */
441 long double
442 log10l(long double x)
444 #if LDBL_MAX_EXP > DBL_MAX_EXP
445 if (x > DBL_MAX)
447 double val;
448 int p2_result = 0;
449 if (x > 0x1p16383L) { p2_result += 16383; x /= 0x1p16383L; }
450 if (x > 0x1p8191L) { p2_result += 8191; x /= 0x1p8191L; }
451 if (x > 0x1p4095L) { p2_result += 4095; x /= 0x1p4095L; }
452 if (x > 0x1p2047L) { p2_result += 2047; x /= 0x1p2047L; }
453 if (x > 0x1p1023L) { p2_result += 1023; x /= 0x1p1023L; }
454 val = log10 ((double) x);
455 return (val + p2_result * .30102999566398119521373889472449302L);
457 #endif
458 #if LDBL_MIN_EXP < DBL_MIN_EXP
459 if (x < DBL_MIN)
461 double val;
462 int p2_result = 0;
463 if (x < 0x1p-16380L) { p2_result += 16380; x /= 0x1p-16380L; }
464 if (x < 0x1p-8189L) { p2_result += 8189; x /= 0x1p-8189L; }
465 if (x < 0x1p-4093L) { p2_result += 4093; x /= 0x1p-4093L; }
466 if (x < 0x1p-2045L) { p2_result += 2045; x /= 0x1p-2045L; }
467 if (x < 0x1p-1021L) { p2_result += 1021; x /= 0x1p-1021L; }
468 val = fabs(log10 ((double) x));
469 return (- val - p2_result * .30102999566398119521373889472449302L);
471 #endif
472 return log10 (x);
474 #endif
477 #if !defined(HAVE_CABSF)
478 #define HAVE_CABSF 1
479 float
480 cabsf (float complex z)
482 return hypotf (REALPART (z), IMAGPART (z));
484 #endif
486 #if !defined(HAVE_CABS)
487 #define HAVE_CABS 1
488 double
489 cabs (double complex z)
491 return hypot (REALPART (z), IMAGPART (z));
493 #endif
495 #if !defined(HAVE_CABSL) && defined(HAVE_HYPOTL)
496 #define HAVE_CABSL 1
497 long double
498 cabsl (long double complex z)
500 return hypotl (REALPART (z), IMAGPART (z));
502 #endif
505 #if !defined(HAVE_CARGF)
506 #define HAVE_CARGF 1
507 float
508 cargf (float complex z)
510 return atan2f (IMAGPART (z), REALPART (z));
512 #endif
514 #if !defined(HAVE_CARG)
515 #define HAVE_CARG 1
516 double
517 carg (double complex z)
519 return atan2 (IMAGPART (z), REALPART (z));
521 #endif
523 #if !defined(HAVE_CARGL) && defined(HAVE_ATAN2L)
524 #define HAVE_CARGL 1
525 long double
526 cargl (long double complex z)
528 return atan2l (IMAGPART (z), REALPART (z));
530 #endif
533 /* exp(z) = exp(a)*(cos(b) + i sin(b)) */
534 #if !defined(HAVE_CEXPF)
535 #define HAVE_CEXPF 1
536 float complex
537 cexpf (float complex z)
539 float a, b;
540 float complex v;
542 a = REALPART (z);
543 b = IMAGPART (z);
544 COMPLEX_ASSIGN (v, cosf (b), sinf (b));
545 return expf (a) * v;
547 #endif
549 #if !defined(HAVE_CEXP)
550 #define HAVE_CEXP 1
551 double complex
552 cexp (double complex z)
554 double a, b;
555 double complex v;
557 a = REALPART (z);
558 b = IMAGPART (z);
559 COMPLEX_ASSIGN (v, cos (b), sin (b));
560 return exp (a) * v;
562 #endif
564 #if !defined(HAVE_CEXPL) && defined(HAVE_COSL) && defined(HAVE_SINL) && defined(EXPL)
565 #define HAVE_CEXPL 1
566 long double complex
567 cexpl (long double complex z)
569 long double a, b;
570 long double complex v;
572 a = REALPART (z);
573 b = IMAGPART (z);
574 COMPLEX_ASSIGN (v, cosl (b), sinl (b));
575 return expl (a) * v;
577 #endif
580 /* log(z) = log (cabs(z)) + i*carg(z) */
581 #if !defined(HAVE_CLOGF)
582 #define HAVE_CLOGF 1
583 float complex
584 clogf (float complex z)
586 float complex v;
588 COMPLEX_ASSIGN (v, logf (cabsf (z)), cargf (z));
589 return v;
591 #endif
593 #if !defined(HAVE_CLOG)
594 #define HAVE_CLOG 1
595 double complex
596 clog (double complex z)
598 double complex v;
600 COMPLEX_ASSIGN (v, log (cabs (z)), carg (z));
601 return v;
603 #endif
605 #if !defined(HAVE_CLOGL) && defined(HAVE_LOGL) && defined(HAVE_CABSL) && defined(HAVE_CARGL)
606 #define HAVE_CLOGL 1
607 long double complex
608 clogl (long double complex z)
610 long double complex v;
612 COMPLEX_ASSIGN (v, logl (cabsl (z)), cargl (z));
613 return v;
615 #endif
618 /* log10(z) = log10 (cabs(z)) + i*carg(z) */
619 #if !defined(HAVE_CLOG10F)
620 #define HAVE_CLOG10F 1
621 float complex
622 clog10f (float complex z)
624 float complex v;
626 COMPLEX_ASSIGN (v, log10f (cabsf (z)), cargf (z));
627 return v;
629 #endif
631 #if !defined(HAVE_CLOG10)
632 #define HAVE_CLOG10 1
633 double complex
634 clog10 (double complex z)
636 double complex v;
638 COMPLEX_ASSIGN (v, log10 (cabs (z)), carg (z));
639 return v;
641 #endif
643 #if !defined(HAVE_CLOG10L) && defined(HAVE_LOG10L) && defined(HAVE_CABSL) && defined(HAVE_CARGL)
644 #define HAVE_CLOG10L 1
645 long double complex
646 clog10l (long double complex z)
648 long double complex v;
650 COMPLEX_ASSIGN (v, log10l (cabsl (z)), cargl (z));
651 return v;
653 #endif
656 /* pow(base, power) = cexp (power * clog (base)) */
657 #if !defined(HAVE_CPOWF)
658 #define HAVE_CPOWF 1
659 float complex
660 cpowf (float complex base, float complex power)
662 return cexpf (power * clogf (base));
664 #endif
666 #if !defined(HAVE_CPOW)
667 #define HAVE_CPOW 1
668 double complex
669 cpow (double complex base, double complex power)
671 return cexp (power * clog (base));
673 #endif
675 #if !defined(HAVE_CPOWL) && defined(HAVE_CEXPL) && defined(HAVE_CLOGL)
676 #define HAVE_CPOWL 1
677 long double complex
678 cpowl (long double complex base, long double complex power)
680 return cexpl (power * clogl (base));
682 #endif
685 /* sqrt(z). Algorithm pulled from glibc. */
686 #if !defined(HAVE_CSQRTF)
687 #define HAVE_CSQRTF 1
688 float complex
689 csqrtf (float complex z)
691 float re, im;
692 float complex v;
694 re = REALPART (z);
695 im = IMAGPART (z);
696 if (im == 0)
698 if (re < 0)
700 COMPLEX_ASSIGN (v, 0, copysignf (sqrtf (-re), im));
702 else
704 COMPLEX_ASSIGN (v, fabsf (sqrtf (re)), copysignf (0, im));
707 else if (re == 0)
709 float r;
711 r = sqrtf (0.5 * fabsf (im));
713 COMPLEX_ASSIGN (v, r, copysignf (r, im));
715 else
717 float d, r, s;
719 d = hypotf (re, im);
720 /* Use the identity 2 Re res Im res = Im x
721 to avoid cancellation error in d +/- Re x. */
722 if (re > 0)
724 r = sqrtf (0.5 * d + 0.5 * re);
725 s = (0.5 * im) / r;
727 else
729 s = sqrtf (0.5 * d - 0.5 * re);
730 r = fabsf ((0.5 * im) / s);
733 COMPLEX_ASSIGN (v, r, copysignf (s, im));
735 return v;
737 #endif
739 #if !defined(HAVE_CSQRT)
740 #define HAVE_CSQRT 1
741 double complex
742 csqrt (double complex z)
744 double re, im;
745 double complex v;
747 re = REALPART (z);
748 im = IMAGPART (z);
749 if (im == 0)
751 if (re < 0)
753 COMPLEX_ASSIGN (v, 0, copysign (sqrt (-re), im));
755 else
757 COMPLEX_ASSIGN (v, fabs (sqrt (re)), copysign (0, im));
760 else if (re == 0)
762 double r;
764 r = sqrt (0.5 * fabs (im));
766 COMPLEX_ASSIGN (v, r, copysign (r, im));
768 else
770 double d, r, s;
772 d = hypot (re, im);
773 /* Use the identity 2 Re res Im res = Im x
774 to avoid cancellation error in d +/- Re x. */
775 if (re > 0)
777 r = sqrt (0.5 * d + 0.5 * re);
778 s = (0.5 * im) / r;
780 else
782 s = sqrt (0.5 * d - 0.5 * re);
783 r = fabs ((0.5 * im) / s);
786 COMPLEX_ASSIGN (v, r, copysign (s, im));
788 return v;
790 #endif
792 #if !defined(HAVE_CSQRTL) && defined(HAVE_COPYSIGNL) && defined(HAVE_SQRTL) && defined(HAVE_FABSL) && defined(HAVE_HYPOTL)
793 #define HAVE_CSQRTL 1
794 long double complex
795 csqrtl (long double complex z)
797 long double re, im;
798 long double complex v;
800 re = REALPART (z);
801 im = IMAGPART (z);
802 if (im == 0)
804 if (re < 0)
806 COMPLEX_ASSIGN (v, 0, copysignl (sqrtl (-re), im));
808 else
810 COMPLEX_ASSIGN (v, fabsl (sqrtl (re)), copysignl (0, im));
813 else if (re == 0)
815 long double r;
817 r = sqrtl (0.5 * fabsl (im));
819 COMPLEX_ASSIGN (v, copysignl (r, im), r);
821 else
823 long double d, r, s;
825 d = hypotl (re, im);
826 /* Use the identity 2 Re res Im res = Im x
827 to avoid cancellation error in d +/- Re x. */
828 if (re > 0)
830 r = sqrtl (0.5 * d + 0.5 * re);
831 s = (0.5 * im) / r;
833 else
835 s = sqrtl (0.5 * d - 0.5 * re);
836 r = fabsl ((0.5 * im) / s);
839 COMPLEX_ASSIGN (v, r, copysignl (s, im));
841 return v;
843 #endif
846 /* sinh(a + i b) = sinh(a) cos(b) + i cosh(a) sin(b) */
847 #if !defined(HAVE_CSINHF)
848 #define HAVE_CSINHF 1
849 float complex
850 csinhf (float complex a)
852 float r, i;
853 float complex v;
855 r = REALPART (a);
856 i = IMAGPART (a);
857 COMPLEX_ASSIGN (v, sinhf (r) * cosf (i), coshf (r) * sinf (i));
858 return v;
860 #endif
862 #if !defined(HAVE_CSINH)
863 #define HAVE_CSINH 1
864 double complex
865 csinh (double complex a)
867 double r, i;
868 double complex v;
870 r = REALPART (a);
871 i = IMAGPART (a);
872 COMPLEX_ASSIGN (v, sinh (r) * cos (i), cosh (r) * sin (i));
873 return v;
875 #endif
877 #if !defined(HAVE_CSINHL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
878 #define HAVE_CSINHL 1
879 long double complex
880 csinhl (long double complex a)
882 long double r, i;
883 long double complex v;
885 r = REALPART (a);
886 i = IMAGPART (a);
887 COMPLEX_ASSIGN (v, sinhl (r) * cosl (i), coshl (r) * sinl (i));
888 return v;
890 #endif
893 /* cosh(a + i b) = cosh(a) cos(b) - i sinh(a) sin(b) */
894 #if !defined(HAVE_CCOSHF)
895 #define HAVE_CCOSHF 1
896 float complex
897 ccoshf (float complex a)
899 float r, i;
900 float complex v;
902 r = REALPART (a);
903 i = IMAGPART (a);
904 COMPLEX_ASSIGN (v, coshf (r) * cosf (i), - (sinhf (r) * sinf (i)));
905 return v;
907 #endif
909 #if !defined(HAVE_CCOSH)
910 #define HAVE_CCOSH 1
911 double complex
912 ccosh (double complex a)
914 double r, i;
915 double complex v;
917 r = REALPART (a);
918 i = IMAGPART (a);
919 COMPLEX_ASSIGN (v, cosh (r) * cos (i), - (sinh (r) * sin (i)));
920 return v;
922 #endif
924 #if !defined(HAVE_CCOSHL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
925 #define HAVE_CCOSHL 1
926 long double complex
927 ccoshl (long double complex a)
929 long double r, i;
930 long double complex v;
932 r = REALPART (a);
933 i = IMAGPART (a);
934 COMPLEX_ASSIGN (v, coshl (r) * cosl (i), - (sinhl (r) * sinl (i)));
935 return v;
937 #endif
940 /* tanh(a + i b) = (tanh(a) + i tan(b)) / (1 - i tanh(a) tan(b)) */
941 #if !defined(HAVE_CTANHF)
942 #define HAVE_CTANHF 1
943 float complex
944 ctanhf (float complex a)
946 float rt, it;
947 float complex n, d;
949 rt = tanhf (REALPART (a));
950 it = tanf (IMAGPART (a));
951 COMPLEX_ASSIGN (n, rt, it);
952 COMPLEX_ASSIGN (d, 1, - (rt * it));
954 return n / d;
956 #endif
958 #if !defined(HAVE_CTANH)
959 #define HAVE_CTANH 1
960 double complex
961 ctanh (double complex a)
963 double rt, it;
964 double complex n, d;
966 rt = tanh (REALPART (a));
967 it = tan (IMAGPART (a));
968 COMPLEX_ASSIGN (n, rt, it);
969 COMPLEX_ASSIGN (d, 1, - (rt * it));
971 return n / d;
973 #endif
975 #if !defined(HAVE_CTANHL) && defined(HAVE_TANL) && defined(HAVE_TANHL)
976 #define HAVE_CTANHL 1
977 long double complex
978 ctanhl (long double complex a)
980 long double rt, it;
981 long double complex n, d;
983 rt = tanhl (REALPART (a));
984 it = tanl (IMAGPART (a));
985 COMPLEX_ASSIGN (n, rt, it);
986 COMPLEX_ASSIGN (d, 1, - (rt * it));
988 return n / d;
990 #endif
993 /* sin(a + i b) = sin(a) cosh(b) + i cos(a) sinh(b) */
994 #if !defined(HAVE_CSINF)
995 #define HAVE_CSINF 1
996 float complex
997 csinf (float complex a)
999 float r, i;
1000 float complex v;
1002 r = REALPART (a);
1003 i = IMAGPART (a);
1004 COMPLEX_ASSIGN (v, sinf (r) * coshf (i), cosf (r) * sinhf (i));
1005 return v;
1007 #endif
1009 #if !defined(HAVE_CSIN)
1010 #define HAVE_CSIN 1
1011 double complex
1012 csin (double complex a)
1014 double r, i;
1015 double complex v;
1017 r = REALPART (a);
1018 i = IMAGPART (a);
1019 COMPLEX_ASSIGN (v, sin (r) * cosh (i), cos (r) * sinh (i));
1020 return v;
1022 #endif
1024 #if !defined(HAVE_CSINL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
1025 #define HAVE_CSINL 1
1026 long double complex
1027 csinl (long double complex a)
1029 long double r, i;
1030 long double complex v;
1032 r = REALPART (a);
1033 i = IMAGPART (a);
1034 COMPLEX_ASSIGN (v, sinl (r) * coshl (i), cosl (r) * sinhl (i));
1035 return v;
1037 #endif
1040 /* cos(a + i b) = cos(a) cosh(b) - i sin(a) sinh(b) */
1041 #if !defined(HAVE_CCOSF)
1042 #define HAVE_CCOSF 1
1043 float complex
1044 ccosf (float complex a)
1046 float r, i;
1047 float complex v;
1049 r = REALPART (a);
1050 i = IMAGPART (a);
1051 COMPLEX_ASSIGN (v, cosf (r) * coshf (i), - (sinf (r) * sinhf (i)));
1052 return v;
1054 #endif
1056 #if !defined(HAVE_CCOS)
1057 #define HAVE_CCOS 1
1058 double complex
1059 ccos (double complex a)
1061 double r, i;
1062 double complex v;
1064 r = REALPART (a);
1065 i = IMAGPART (a);
1066 COMPLEX_ASSIGN (v, cos (r) * cosh (i), - (sin (r) * sinh (i)));
1067 return v;
1069 #endif
1071 #if !defined(HAVE_CCOSL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
1072 #define HAVE_CCOSL 1
1073 long double complex
1074 ccosl (long double complex a)
1076 long double r, i;
1077 long double complex v;
1079 r = REALPART (a);
1080 i = IMAGPART (a);
1081 COMPLEX_ASSIGN (v, cosl (r) * coshl (i), - (sinl (r) * sinhl (i)));
1082 return v;
1084 #endif
1087 /* tan(a + i b) = (tan(a) + i tanh(b)) / (1 - i tan(a) tanh(b)) */
1088 #if !defined(HAVE_CTANF)
1089 #define HAVE_CTANF 1
1090 float complex
1091 ctanf (float complex a)
1093 float rt, it;
1094 float complex n, d;
1096 rt = tanf (REALPART (a));
1097 it = tanhf (IMAGPART (a));
1098 COMPLEX_ASSIGN (n, rt, it);
1099 COMPLEX_ASSIGN (d, 1, - (rt * it));
1101 return n / d;
1103 #endif
1105 #if !defined(HAVE_CTAN)
1106 #define HAVE_CTAN 1
1107 double complex
1108 ctan (double complex a)
1110 double rt, it;
1111 double complex n, d;
1113 rt = tan (REALPART (a));
1114 it = tanh (IMAGPART (a));
1115 COMPLEX_ASSIGN (n, rt, it);
1116 COMPLEX_ASSIGN (d, 1, - (rt * it));
1118 return n / d;
1120 #endif
1122 #if !defined(HAVE_CTANL) && defined(HAVE_TANL) && defined(HAVE_TANHL)
1123 #define HAVE_CTANL 1
1124 long double complex
1125 ctanl (long double complex a)
1127 long double rt, it;
1128 long double complex n, d;
1130 rt = tanl (REALPART (a));
1131 it = tanhl (IMAGPART (a));
1132 COMPLEX_ASSIGN (n, rt, it);
1133 COMPLEX_ASSIGN (d, 1, - (rt * it));
1135 return n / d;
1137 #endif