]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libgfortran/intrinsics/c99_functions.c
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
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. */
32 #define C99_PROTOS_H WE_DONT_WANT_PROTOS_NOW
33 #include "libgfortran.h"
35 /* IRIX's <math.h> declares a non-C99 compliant implementation of cabs,
36 which takes two floating point arguments instead of a single complex.
37 If <complex.h> is missing this prevents building of c99_functions.c.
38 To work around this we redirect cabs{,f,l} calls to __gfc_cabs{,f,l}. */
40 #if defined(__sgi__) && !defined(HAVE_COMPLEX_H)
44 #define cabs __gfc_cabs
45 #define cabsf __gfc_cabsf
46 #define cabsl __gfc_cabsl
49 /* Tru64's <math.h> declares a non-C99 compliant implementation of cabs,
50 which takes two floating point arguments instead of a single complex.
51 To work around this we redirect cabs{,f,l} calls to __gfc_cabs{,f,l}. */
57 #define cabs __gfc_cabs
58 #define cabsf __gfc_cabsf
59 #define cabsl __gfc_cabsl
62 /* Prototypes to silence -Wstrict-prototypes -Wmissing-prototypes. */
64 float cabsf(float complex);
65 double cabs(double complex);
66 long double cabsl(long double complex);
68 float cargf(float complex);
69 double carg(double complex);
70 long double cargl(long double complex);
72 float complex clog10f(float complex);
73 double complex clog10(double complex);
74 long double complex clog10l(long double complex);
77 /* Wrappers for systems without the various C99 single precision Bessel
80 #if defined(HAVE_J0) && ! defined(HAVE_J0F)
82 extern float j0f (float);
87 return (float) j0 ((double) x
);
91 #if defined(HAVE_J1) && !defined(HAVE_J1F)
93 extern float j1f (float);
97 return (float) j1 ((double) x
);
101 #if defined(HAVE_JN) && !defined(HAVE_JNF)
103 extern float jnf (int, float);
108 return (float) jn (n
, (double) x
);
112 #if defined(HAVE_Y0) && !defined(HAVE_Y0F)
114 extern float y0f (float);
119 return (float) y0 ((double) x
);
123 #if defined(HAVE_Y1) && !defined(HAVE_Y1F)
125 extern float y1f (float);
130 return (float) y1 ((double) x
);
134 #if defined(HAVE_YN) && !defined(HAVE_YNF)
136 extern float ynf (int, float);
141 return (float) yn (n
, (double) x
);
146 /* Wrappers for systems without the C99 erff() and erfcf() functions. */
148 #if defined(HAVE_ERF) && !defined(HAVE_ERFF)
150 extern float erff (float);
155 return (float) erf ((double) x
);
159 #if defined(HAVE_ERFC) && !defined(HAVE_ERFCF)
161 extern float erfcf (float);
166 return (float) erfc ((double) x
);
176 return (float) acos(x
);
180 #if HAVE_ACOSH && !HAVE_ACOSHF
184 return (float) acosh ((double) x
);
193 return (float) asin(x
);
197 #if HAVE_ASINH && !HAVE_ASINHF
201 return (float) asinh ((double) x
);
206 #define HAVE_ATAN2F 1
208 atan2f(float y
, float x
)
210 return (float) atan2(y
, x
);
219 return (float) atan(x
);
223 #if HAVE_ATANH && !HAVE_ATANHF
227 return (float) atanh ((double) x
);
236 return (float) ceil(x
);
240 #ifndef HAVE_COPYSIGNF
241 #define HAVE_COPYSIGNF 1
243 copysignf(float x
, float y
)
245 return (float) copysign(x
, y
);
254 return (float) cos(x
);
263 return (float) cosh(x
);
272 return (float) exp(x
);
281 return (float) fabs(x
);
286 #define HAVE_FLOORF 1
290 return (float) floor(x
);
297 fmodf (float x
, float y
)
299 return (float) fmod (x
, y
);
304 #define HAVE_FREXPF 1
306 frexpf(float x
, int *exp
)
308 return (float) frexp(x
, exp
);
313 #define HAVE_HYPOTF 1
315 hypotf(float x
, float y
)
317 return (float) hypot(x
, y
);
326 return (float) log(x
);
331 #define HAVE_LOG10F 1
335 return (float) log10(x
);
340 #define HAVE_SCALBN 1
342 scalbn(double x
, int y
)
344 #if (FLT_RADIX == 2) && defined(HAVE_LDEXP)
347 return x
* pow(FLT_RADIX
, y
);
353 #define HAVE_SCALBNF 1
355 scalbnf(float x
, int y
)
357 return (float) scalbn(x
, y
);
366 return (float) sin(x
);
375 return (float) sinh(x
);
384 return (float) sqrt(x
);
393 return (float) tan(x
);
402 return (float) tanh(x
);
422 #define HAVE_TRUNCF 1
426 return (float) trunc (x
);
430 #ifndef HAVE_NEXTAFTERF
431 #define HAVE_NEXTAFTERF 1
432 /* This is a portable implementation of nextafterf that is intended to be
433 independent of the floating point format or its in memory representation.
434 This implementation works correctly with denormalized values. */
436 nextafterf(float x
, float y
)
438 /* This variable is marked volatile to avoid excess precision problems
439 on some platforms, including IA-32. */
440 volatile float delta
;
441 float absx
, denorm_min
;
443 if (isnan(x
) || isnan(y
))
448 return x
> 0 ? __FLT_MAX__
: - __FLT_MAX__
;
450 /* absx = fabsf (x); */
451 absx
= (x
< 0.0) ? -x
: x
;
453 /* __FLT_DENORM_MIN__ is non-zero iff the target supports denormals. */
454 if (__FLT_DENORM_MIN__
== 0.0f
)
455 denorm_min
= __FLT_MIN__
;
457 denorm_min
= __FLT_DENORM_MIN__
;
459 if (absx
< __FLT_MIN__
)
466 /* Discard the fraction from x. */
467 frac
= frexpf (absx
, &exp
);
468 delta
= scalbnf (0.5f
, exp
);
470 /* Scale x by the epsilon of the representation. By rights we should
471 have been able to combine this with scalbnf, but some targets don't
472 get that correct with denormals. */
473 delta
*= __FLT_EPSILON__
;
475 /* If we're going to be reducing the absolute value of X, and doing so
476 would reduce the exponent of X, then the delta to be applied is
477 one exponent smaller. */
478 if (frac
== 0.5f
&& (y
< x
) == (x
> 0))
481 /* If that underflows to zero, then we're back to the minimum. */
494 #if !defined(HAVE_POWF) || defined(HAVE_BROKEN_POWF)
499 powf(float x
, float y
)
501 return (float) pow(x
, y
);
505 /* Note that if fpclassify is not defined, then NaN is not handled */
507 /* Algorithm by Steven G. Kargl. */
509 #if !defined(HAVE_ROUNDL)
510 #define HAVE_ROUNDL 1
511 #if defined(HAVE_CEILL)
512 /* Round to nearest integral value. If the argument is halfway between two
513 integral values then round away from zero. */
516 roundl(long double x
)
539 /* Poor version of roundl for system that don't have ceill. */
541 roundl(long double x
)
543 if (x
> DBL_MAX
|| x
< -DBL_MAX
)
545 #ifdef HAVE_NEXTAFTERL
546 static long double prechalf
= nexafterl (0.5L, LDBL_MAX
);
548 static long double prechalf
= 0.5L;
550 return (GFC_INTEGER_LARGEST
) (x
+ (x
> 0 ? prechalf
: -prechalf
));
554 return round((double) x
);
562 /* Round to nearest integral value. If the argument is halfway between two
563 integral values then round away from zero. */
590 #define HAVE_ROUNDF 1
591 /* Round to nearest integral value. If the argument is halfway between two
592 integral values then round away from zero. */
619 /* lround{f,,l} and llround{f,,l} functions. */
621 #if !defined(HAVE_LROUNDF) && defined(HAVE_ROUNDF)
622 #define HAVE_LROUNDF 1
626 return (long int) roundf (x
);
630 #if !defined(HAVE_LROUND) && defined(HAVE_ROUND)
631 #define HAVE_LROUND 1
635 return (long int) round (x
);
639 #if !defined(HAVE_LROUNDL) && defined(HAVE_ROUNDL)
640 #define HAVE_LROUNDL 1
642 lroundl (long double x
)
644 return (long long int) roundl (x
);
648 #if !defined(HAVE_LLROUNDF) && defined(HAVE_ROUNDF)
649 #define HAVE_LLROUNDF 1
653 return (long long int) roundf (x
);
657 #if !defined(HAVE_LLROUND) && defined(HAVE_ROUND)
658 #define HAVE_LLROUND 1
662 return (long long int) round (x
);
666 #if !defined(HAVE_LLROUNDL) && defined(HAVE_ROUNDL)
667 #define HAVE_LLROUNDL 1
669 llroundl (long double x
)
671 return (long long int) roundl (x
);
677 #define HAVE_LOG10L 1
678 /* log10 function for long double variables. The version provided here
679 reduces the argument until it fits into a double, then use log10. */
681 log10l(long double x
)
683 #if LDBL_MAX_EXP > DBL_MAX_EXP
688 if (x
> 0x1p
16383L) { p2_result
+= 16383; x
/= 0x1p
16383L; }
689 if (x
> 0x1p
8191L) { p2_result
+= 8191; x
/= 0x1p
8191L; }
690 if (x
> 0x1p
4095L) { p2_result
+= 4095; x
/= 0x1p
4095L; }
691 if (x
> 0x1p
2047L) { p2_result
+= 2047; x
/= 0x1p
2047L; }
692 if (x
> 0x1p
1023L) { p2_result
+= 1023; x
/= 0x1p
1023L; }
693 val
= log10 ((double) x
);
694 return (val
+ p2_result
* .30102999566398119521373889472449302L);
697 #if LDBL_MIN_EXP < DBL_MIN_EXP
702 if (x
< 0x1p
-16380L) { p2_result
+= 16380; x
/= 0x1p
-16380L; }
703 if (x
< 0x1p
-8189L) { p2_result
+= 8189; x
/= 0x1p
-8189L; }
704 if (x
< 0x1p
-4093L) { p2_result
+= 4093; x
/= 0x1p
-4093L; }
705 if (x
< 0x1p
-2045L) { p2_result
+= 2045; x
/= 0x1p
-2045L; }
706 if (x
< 0x1p
-1021L) { p2_result
+= 1021; x
/= 0x1p
-1021L; }
707 val
= fabs(log10 ((double) x
));
708 return (- val
- p2_result
* .30102999566398119521373889472449302L);
717 #define HAVE_FLOORL 1
719 floorl (long double x
)
721 /* Zero, possibly signed. */
725 /* Large magnitude. */
726 if (x
> DBL_MAX
|| x
< (-DBL_MAX
))
729 /* Small positive values. */
730 if (x
>= 0 && x
< DBL_MIN
)
733 /* Small negative values. */
734 if (x
< 0 && x
> (-DBL_MIN
))
745 fmodl (long double x
, long double y
)
750 /* Need to check that the result has the same sign as x and magnitude
751 less than the magnitude of y. */
752 return x
- floorl (x
/ y
) * y
;
757 #if !defined(HAVE_CABSF)
760 cabsf (float complex z
)
762 return hypotf (REALPART (z
), IMAGPART (z
));
766 #if !defined(HAVE_CABS)
769 cabs (double complex z
)
771 return hypot (REALPART (z
), IMAGPART (z
));
775 #if !defined(HAVE_CABSL) && defined(HAVE_HYPOTL)
778 cabsl (long double complex z
)
780 return hypotl (REALPART (z
), IMAGPART (z
));
785 #if !defined(HAVE_CARGF)
788 cargf (float complex z
)
790 return atan2f (IMAGPART (z
), REALPART (z
));
794 #if !defined(HAVE_CARG)
797 carg (double complex z
)
799 return atan2 (IMAGPART (z
), REALPART (z
));
803 #if !defined(HAVE_CARGL) && defined(HAVE_ATAN2L)
806 cargl (long double complex z
)
808 return atan2l (IMAGPART (z
), REALPART (z
));
813 /* exp(z) = exp(a)*(cos(b) + i sin(b)) */
814 #if !defined(HAVE_CEXPF)
817 cexpf (float complex z
)
824 COMPLEX_ASSIGN (v
, cosf (b
), sinf (b
));
829 #if !defined(HAVE_CEXP)
832 cexp (double complex z
)
839 COMPLEX_ASSIGN (v
, cos (b
), sin (b
));
844 #if !defined(HAVE_CEXPL) && defined(HAVE_COSL) && defined(HAVE_SINL) && defined(EXPL)
847 cexpl (long double complex z
)
850 long double complex v
;
854 COMPLEX_ASSIGN (v
, cosl (b
), sinl (b
));
860 /* log(z) = log (cabs(z)) + i*carg(z) */
861 #if !defined(HAVE_CLOGF)
864 clogf (float complex z
)
868 COMPLEX_ASSIGN (v
, logf (cabsf (z
)), cargf (z
));
873 #if !defined(HAVE_CLOG)
876 clog (double complex z
)
880 COMPLEX_ASSIGN (v
, log (cabs (z
)), carg (z
));
885 #if !defined(HAVE_CLOGL) && defined(HAVE_LOGL) && defined(HAVE_CABSL) && defined(HAVE_CARGL)
888 clogl (long double complex z
)
890 long double complex v
;
892 COMPLEX_ASSIGN (v
, logl (cabsl (z
)), cargl (z
));
898 /* log10(z) = log10 (cabs(z)) + i*carg(z) */
899 #if !defined(HAVE_CLOG10F)
900 #define HAVE_CLOG10F 1
902 clog10f (float complex z
)
906 COMPLEX_ASSIGN (v
, log10f (cabsf (z
)), cargf (z
));
911 #if !defined(HAVE_CLOG10)
912 #define HAVE_CLOG10 1
914 clog10 (double complex z
)
918 COMPLEX_ASSIGN (v
, log10 (cabs (z
)), carg (z
));
923 #if !defined(HAVE_CLOG10L) && defined(HAVE_LOG10L) && defined(HAVE_CABSL) && defined(HAVE_CARGL)
924 #define HAVE_CLOG10L 1
926 clog10l (long double complex z
)
928 long double complex v
;
930 COMPLEX_ASSIGN (v
, log10l (cabsl (z
)), cargl (z
));
936 /* pow(base, power) = cexp (power * clog (base)) */
937 #if !defined(HAVE_CPOWF)
940 cpowf (float complex base
, float complex power
)
942 return cexpf (power
* clogf (base
));
946 #if !defined(HAVE_CPOW)
949 cpow (double complex base
, double complex power
)
951 return cexp (power
* clog (base
));
955 #if !defined(HAVE_CPOWL) && defined(HAVE_CEXPL) && defined(HAVE_CLOGL)
958 cpowl (long double complex base
, long double complex power
)
960 return cexpl (power
* clogl (base
));
965 /* sqrt(z). Algorithm pulled from glibc. */
966 #if !defined(HAVE_CSQRTF)
967 #define HAVE_CSQRTF 1
969 csqrtf (float complex z
)
980 COMPLEX_ASSIGN (v
, 0, copysignf (sqrtf (-re
), im
));
984 COMPLEX_ASSIGN (v
, fabsf (sqrtf (re
)), copysignf (0, im
));
991 r
= sqrtf (0.5 * fabsf (im
));
993 COMPLEX_ASSIGN (v
, r
, copysignf (r
, im
));
1000 /* Use the identity 2 Re res Im res = Im x
1001 to avoid cancellation error in d +/- Re x. */
1004 r
= sqrtf (0.5 * d
+ 0.5 * re
);
1009 s
= sqrtf (0.5 * d
- 0.5 * re
);
1010 r
= fabsf ((0.5 * im
) / s
);
1013 COMPLEX_ASSIGN (v
, r
, copysignf (s
, im
));
1019 #if !defined(HAVE_CSQRT)
1020 #define HAVE_CSQRT 1
1022 csqrt (double complex z
)
1033 COMPLEX_ASSIGN (v
, 0, copysign (sqrt (-re
), im
));
1037 COMPLEX_ASSIGN (v
, fabs (sqrt (re
)), copysign (0, im
));
1044 r
= sqrt (0.5 * fabs (im
));
1046 COMPLEX_ASSIGN (v
, r
, copysign (r
, im
));
1053 /* Use the identity 2 Re res Im res = Im x
1054 to avoid cancellation error in d +/- Re x. */
1057 r
= sqrt (0.5 * d
+ 0.5 * re
);
1062 s
= sqrt (0.5 * d
- 0.5 * re
);
1063 r
= fabs ((0.5 * im
) / s
);
1066 COMPLEX_ASSIGN (v
, r
, copysign (s
, im
));
1072 #if !defined(HAVE_CSQRTL) && defined(HAVE_COPYSIGNL) && defined(HAVE_SQRTL) && defined(HAVE_FABSL) && defined(HAVE_HYPOTL)
1073 #define HAVE_CSQRTL 1
1075 csqrtl (long double complex z
)
1078 long double complex v
;
1086 COMPLEX_ASSIGN (v
, 0, copysignl (sqrtl (-re
), im
));
1090 COMPLEX_ASSIGN (v
, fabsl (sqrtl (re
)), copysignl (0, im
));
1097 r
= sqrtl (0.5 * fabsl (im
));
1099 COMPLEX_ASSIGN (v
, copysignl (r
, im
), r
);
1103 long double d
, r
, s
;
1105 d
= hypotl (re
, im
);
1106 /* Use the identity 2 Re res Im res = Im x
1107 to avoid cancellation error in d +/- Re x. */
1110 r
= sqrtl (0.5 * d
+ 0.5 * re
);
1115 s
= sqrtl (0.5 * d
- 0.5 * re
);
1116 r
= fabsl ((0.5 * im
) / s
);
1119 COMPLEX_ASSIGN (v
, r
, copysignl (s
, im
));
1126 /* sinh(a + i b) = sinh(a) cos(b) + i cosh(a) sin(b) */
1127 #if !defined(HAVE_CSINHF)
1128 #define HAVE_CSINHF 1
1130 csinhf (float complex a
)
1137 COMPLEX_ASSIGN (v
, sinhf (r
) * cosf (i
), coshf (r
) * sinf (i
));
1142 #if !defined(HAVE_CSINH)
1143 #define HAVE_CSINH 1
1145 csinh (double complex a
)
1152 COMPLEX_ASSIGN (v
, sinh (r
) * cos (i
), cosh (r
) * sin (i
));
1157 #if !defined(HAVE_CSINHL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
1158 #define HAVE_CSINHL 1
1160 csinhl (long double complex a
)
1163 long double complex v
;
1167 COMPLEX_ASSIGN (v
, sinhl (r
) * cosl (i
), coshl (r
) * sinl (i
));
1173 /* cosh(a + i b) = cosh(a) cos(b) - i sinh(a) sin(b) */
1174 #if !defined(HAVE_CCOSHF)
1175 #define HAVE_CCOSHF 1
1177 ccoshf (float complex a
)
1184 COMPLEX_ASSIGN (v
, coshf (r
) * cosf (i
), - (sinhf (r
) * sinf (i
)));
1189 #if !defined(HAVE_CCOSH)
1190 #define HAVE_CCOSH 1
1192 ccosh (double complex a
)
1199 COMPLEX_ASSIGN (v
, cosh (r
) * cos (i
), - (sinh (r
) * sin (i
)));
1204 #if !defined(HAVE_CCOSHL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
1205 #define HAVE_CCOSHL 1
1207 ccoshl (long double complex a
)
1210 long double complex v
;
1214 COMPLEX_ASSIGN (v
, coshl (r
) * cosl (i
), - (sinhl (r
) * sinl (i
)));
1220 /* tanh(a + i b) = (tanh(a) + i tan(b)) / (1 - i tanh(a) tan(b)) */
1221 #if !defined(HAVE_CTANHF)
1222 #define HAVE_CTANHF 1
1224 ctanhf (float complex a
)
1229 rt
= tanhf (REALPART (a
));
1230 it
= tanf (IMAGPART (a
));
1231 COMPLEX_ASSIGN (n
, rt
, it
);
1232 COMPLEX_ASSIGN (d
, 1, - (rt
* it
));
1238 #if !defined(HAVE_CTANH)
1239 #define HAVE_CTANH 1
1241 ctanh (double complex a
)
1244 double complex n
, d
;
1246 rt
= tanh (REALPART (a
));
1247 it
= tan (IMAGPART (a
));
1248 COMPLEX_ASSIGN (n
, rt
, it
);
1249 COMPLEX_ASSIGN (d
, 1, - (rt
* it
));
1255 #if !defined(HAVE_CTANHL) && defined(HAVE_TANL) && defined(HAVE_TANHL)
1256 #define HAVE_CTANHL 1
1258 ctanhl (long double complex a
)
1261 long double complex n
, d
;
1263 rt
= tanhl (REALPART (a
));
1264 it
= tanl (IMAGPART (a
));
1265 COMPLEX_ASSIGN (n
, rt
, it
);
1266 COMPLEX_ASSIGN (d
, 1, - (rt
* it
));
1273 /* sin(a + i b) = sin(a) cosh(b) + i cos(a) sinh(b) */
1274 #if !defined(HAVE_CSINF)
1275 #define HAVE_CSINF 1
1277 csinf (float complex a
)
1284 COMPLEX_ASSIGN (v
, sinf (r
) * coshf (i
), cosf (r
) * sinhf (i
));
1289 #if !defined(HAVE_CSIN)
1292 csin (double complex a
)
1299 COMPLEX_ASSIGN (v
, sin (r
) * cosh (i
), cos (r
) * sinh (i
));
1304 #if !defined(HAVE_CSINL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
1305 #define HAVE_CSINL 1
1307 csinl (long double complex a
)
1310 long double complex v
;
1314 COMPLEX_ASSIGN (v
, sinl (r
) * coshl (i
), cosl (r
) * sinhl (i
));
1320 /* cos(a + i b) = cos(a) cosh(b) - i sin(a) sinh(b) */
1321 #if !defined(HAVE_CCOSF)
1322 #define HAVE_CCOSF 1
1324 ccosf (float complex a
)
1331 COMPLEX_ASSIGN (v
, cosf (r
) * coshf (i
), - (sinf (r
) * sinhf (i
)));
1336 #if !defined(HAVE_CCOS)
1339 ccos (double complex a
)
1346 COMPLEX_ASSIGN (v
, cos (r
) * cosh (i
), - (sin (r
) * sinh (i
)));
1351 #if !defined(HAVE_CCOSL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
1352 #define HAVE_CCOSL 1
1354 ccosl (long double complex a
)
1357 long double complex v
;
1361 COMPLEX_ASSIGN (v
, cosl (r
) * coshl (i
), - (sinl (r
) * sinhl (i
)));
1367 /* tan(a + i b) = (tan(a) + i tanh(b)) / (1 - i tan(a) tanh(b)) */
1368 #if !defined(HAVE_CTANF)
1369 #define HAVE_CTANF 1
1371 ctanf (float complex a
)
1376 rt
= tanf (REALPART (a
));
1377 it
= tanhf (IMAGPART (a
));
1378 COMPLEX_ASSIGN (n
, rt
, it
);
1379 COMPLEX_ASSIGN (d
, 1, - (rt
* it
));
1385 #if !defined(HAVE_CTAN)
1388 ctan (double complex a
)
1391 double complex n
, d
;
1393 rt
= tan (REALPART (a
));
1394 it
= tanh (IMAGPART (a
));
1395 COMPLEX_ASSIGN (n
, rt
, it
);
1396 COMPLEX_ASSIGN (d
, 1, - (rt
* it
));
1402 #if !defined(HAVE_CTANL) && defined(HAVE_TANL) && defined(HAVE_TANHL)
1403 #define HAVE_CTANL 1
1405 ctanl (long double complex a
)
1408 long double complex n
, d
;
1410 rt
= tanl (REALPART (a
));
1411 it
= tanhl (IMAGPART (a
));
1412 COMPLEX_ASSIGN (n
, rt
, it
);
1413 COMPLEX_ASSIGN (d
, 1, - (rt
* it
));
1420 #if !defined(HAVE_TGAMMA)
1421 #define HAVE_TGAMMA 1
1423 extern double tgamma (double);
1425 /* Fallback tgamma() function. Uses the algorithm from
1426 http://www.netlib.org/specfun/gamma and references therein. */
1429 #define SQRTPI 0.9189385332046727417803297
1432 #define PI 3.1415926535897932384626434
1438 double fact
, res
, sum
, xden
, xnum
, y
, y1
, ysq
, z
;
1440 static double p
[8] = {
1441 -1.71618513886549492533811e0
, 2.47656508055759199108314e1
,
1442 -3.79804256470945635097577e2
, 6.29331155312818442661052e2
,
1443 8.66966202790413211295064e2
, -3.14512729688483675254357e4
,
1444 -3.61444134186911729807069e4
, 6.64561438202405440627855e4
};
1446 static double q
[8] = {
1447 -3.08402300119738975254353e1
, 3.15350626979604161529144e2
,
1448 -1.01515636749021914166146e3
, -3.10777167157231109440444e3
,
1449 2.25381184209801510330112e4
, 4.75584627752788110767815e3
,
1450 -1.34659959864969306392456e5
, -1.15132259675553483497211e5
};
1452 static double c
[7] = { -1.910444077728e-03,
1453 8.4171387781295e-04, -5.952379913043012e-04,
1454 7.93650793500350248e-04, -2.777777777777681622553e-03,
1455 8.333333333333333331554247e-02, 5.7083835261e-03 };
1457 static const double xminin
= 2.23e-308;
1458 static const double xbig
= 171.624;
1459 static const double xnan
= __builtin_nan ("0x0"), xinf
= __builtin_inf ();
1460 static double eps
= 0;
1463 eps
= nextafter(1., 2.) - 1.;
1470 if (__builtin_isnan (x
))
1481 if (y1
!= trunc(y1
*0.5l)*2)
1483 fact
= -PI
/ sin(PI
*res
);
1487 return x
== 0 ? copysign (xinf
, x
) : xnan
;
1514 for (i
= 0; i
< 8; i
++)
1516 xnum
= (xnum
+ p
[i
]) * z
;
1517 xden
= xden
* z
+ q
[i
];
1520 res
= xnum
/ xden
+ 1;
1525 for (i
= 1; i
<= n
; i
++)
1537 for (i
= 0; i
< 6; i
++)
1538 sum
= sum
/ ysq
+ c
[i
];
1540 sum
= sum
/y
- y
+ SQRTPI
;
1541 sum
= sum
+ (y
- 0.5) * log(y
);
1545 return x
< 0 ? xnan
: xinf
;
1559 #if !defined(HAVE_LGAMMA)
1560 #define HAVE_LGAMMA 1
1562 extern double lgamma (double);
1564 /* Fallback lgamma() function. Uses the algorithm from
1565 http://www.netlib.org/specfun/algama and references therein,
1566 except for negative arguments (where netlib would return +Inf)
1567 where we use the following identity:
1568 lgamma(y) = log(pi/(|y*sin(pi*y)|)) - lgamma(-y)
1576 #define SQRTPI 0.9189385332046727417803297
1579 #define PI 3.1415926535897932384626434
1581 #define PNT68 0.6796875
1582 #define D1 -0.5772156649015328605195174
1583 #define D2 0.4227843350984671393993777
1584 #define D4 1.791759469228055000094023
1586 static double p1
[8] = {
1587 4.945235359296727046734888e0
, 2.018112620856775083915565e2
,
1588 2.290838373831346393026739e3
, 1.131967205903380828685045e4
,
1589 2.855724635671635335736389e4
, 3.848496228443793359990269e4
,
1590 2.637748787624195437963534e4
, 7.225813979700288197698961e3
};
1591 static double q1
[8] = {
1592 6.748212550303777196073036e1
, 1.113332393857199323513008e3
,
1593 7.738757056935398733233834e3
, 2.763987074403340708898585e4
,
1594 5.499310206226157329794414e4
, 6.161122180066002127833352e4
,
1595 3.635127591501940507276287e4
, 8.785536302431013170870835e3
};
1596 static double p2
[8] = {
1597 4.974607845568932035012064e0
, 5.424138599891070494101986e2
,
1598 1.550693864978364947665077e4
, 1.847932904445632425417223e5
,
1599 1.088204769468828767498470e6
, 3.338152967987029735917223e6
,
1600 5.106661678927352456275255e6
, 3.074109054850539556250927e6
};
1601 static double q2
[8] = {
1602 1.830328399370592604055942e2
, 7.765049321445005871323047e3
,
1603 1.331903827966074194402448e5
, 1.136705821321969608938755e6
,
1604 5.267964117437946917577538e6
, 1.346701454311101692290052e7
,
1605 1.782736530353274213975932e7
, 9.533095591844353613395747e6
};
1606 static double p4
[8] = {
1607 1.474502166059939948905062e4
, 2.426813369486704502836312e6
,
1608 1.214755574045093227939592e8
, 2.663432449630976949898078e9
,
1609 2.940378956634553899906876e10
, 1.702665737765398868392998e11
,
1610 4.926125793377430887588120e11
, 5.606251856223951465078242e11
};
1611 static double q4
[8] = {
1612 2.690530175870899333379843e3
, 6.393885654300092398984238e5
,
1613 4.135599930241388052042842e7
, 1.120872109616147941376570e9
,
1614 1.488613728678813811542398e10
, 1.016803586272438228077304e11
,
1615 3.417476345507377132798597e11
, 4.463158187419713286462081e11
};
1616 static double c
[7] = {
1617 -1.910444077728e-03, 8.4171387781295e-04,
1618 -5.952379913043012e-04, 7.93650793500350248e-04,
1619 -2.777777777777681622553e-03, 8.333333333333333331554247e-02,
1622 static double xbig
= 2.55e305
, xinf
= __builtin_inf (), eps
= 0,
1626 double corr
, res
, xden
, xm1
, xm2
, xm4
, xnum
, ysq
;
1629 eps
= __builtin_nextafter(1., 2.) - 1.;
1631 if ((y
> 0) && (y
<= xbig
))
1645 xm1
= (y
- 0.5) - 0.5;
1648 if ((y
<= 0.5) || (y
>= PNT68
))
1652 for (i
= 0; i
< 8; i
++)
1654 xnum
= xnum
*xm1
+ p1
[i
];
1655 xden
= xden
*xm1
+ q1
[i
];
1657 res
= corr
+ (xm1
* (D1
+ xm1
*(xnum
/xden
)));
1661 xm2
= (y
- 0.5) - 0.5;
1664 for (i
= 0; i
< 8; i
++)
1666 xnum
= xnum
*xm2
+ p2
[i
];
1667 xden
= xden
*xm2
+ q2
[i
];
1669 res
= corr
+ xm2
* (D2
+ xm2
*(xnum
/xden
));
1677 for (i
= 0; i
< 8; i
++)
1679 xnum
= xnum
*xm2
+ p2
[i
];
1680 xden
= xden
*xm2
+ q2
[i
];
1682 res
= xm2
* (D2
+ xm2
*(xnum
/xden
));
1689 for (i
= 0; i
< 8; i
++)
1691 xnum
= xnum
*xm4
+ p4
[i
];
1692 xden
= xden
*xm4
+ q4
[i
];
1694 res
= D4
+ xm4
*(xnum
/xden
);
1703 for (i
= 0; i
< 6; i
++)
1704 res
= res
/ ysq
+ c
[i
];
1708 res
= res
+ SQRTPI
- 0.5*corr
;
1709 res
= res
+ y
*(corr
-1);
1712 else if (y
< 0 && __builtin_floor (y
) != y
)
1714 /* lgamma(y) = log(pi/(|y*sin(pi*y)|)) - lgamma(-y)
1715 For abs(y) very close to zero, we use a series expansion to
1716 the first order in y to avoid overflow. */
1718 res
= -2 * log (fabs (y
)) - lgamma (-y
);
1720 res
= log (PI
/ fabs (y
* sin (PI
* y
))) - lgamma (-y
);
1730 #if defined(HAVE_TGAMMA) && !defined(HAVE_TGAMMAF)
1731 #define HAVE_TGAMMAF 1
1732 extern float tgammaf (float);
1737 return (float) tgamma ((double) x
);
1741 #if defined(HAVE_LGAMMA) && !defined(HAVE_LGAMMAF)
1742 #define HAVE_LGAMMAF 1
1743 extern float lgammaf (float);
1748 return (float) lgamma ((double) x
);