]>
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. */
31 #include <sys/types.h>
35 #define C99_PROTOS_H WE_DONT_WANT_PROTOS_NOW
36 #include "libgfortran.h"
38 /* Tru64's <math.h> declares a non-C99 compliant implementation of cabs,
39 which takes two floating point arguments instead of a single complex.
40 To work around this we redirect cabs{,f,l} calls to __gfc_cabs{,f,l}. */
46 #define cabs __gfc_cabs
47 #define cabsf __gfc_cabsf
48 #define cabsl __gfc_cabsl
51 /* Prototypes to silence -Wstrict-prototypes -Wmissing-prototypes. */
53 float cabsf(float complex);
54 double cabs(double complex);
55 long double cabsl(long double complex);
57 float cargf(float complex);
58 double carg(double complex);
59 long double cargl(long double complex);
61 float complex clog10f(float complex);
62 double complex clog10(double complex);
63 long double complex clog10l(long double complex);
71 return (float) acos(x
);
80 return (float) asin(x
);
87 atan2f(float y
, float x
)
89 return (float) atan2(y
, x
);
98 return (float) atan(x
);
107 return (float) ceil(x
);
111 #ifndef HAVE_COPYSIGNF
112 #define HAVE_COPYSIGNF 1
114 copysignf(float x
, float y
)
116 return (float) copysign(x
, y
);
125 return (float) cos(x
);
134 return (float) cosh(x
);
143 return (float) exp(x
);
152 return (float) fabs(x
);
157 #define HAVE_FLOORF 1
161 return (float) floor(x
);
166 #define HAVE_FREXPF 1
168 frexpf(float x
, int *exp
)
170 return (float) frexp(x
, exp
);
175 #define HAVE_HYPOTF 1
177 hypotf(float x
, float y
)
179 return (float) hypot(x
, y
);
188 return (float) log(x
);
193 #define HAVE_LOG10F 1
197 return (float) log10(x
);
202 #define HAVE_SCALBN 1
204 scalbn(double x
, int y
)
206 return x
* pow(FLT_RADIX
, y
);
211 #define HAVE_SCALBNF 1
213 scalbnf(float x
, int y
)
215 return (float) scalbn(x
, y
);
224 return (float) sin(x
);
233 return (float) sinh(x
);
242 return (float) sqrt(x
);
251 return (float) tan(x
);
260 return (float) tanh(x
);
280 #define HAVE_TRUNCF 1
284 return (float) trunc (x
);
288 #ifndef HAVE_NEXTAFTERF
289 #define HAVE_NEXTAFTERF 1
290 /* This is a portable implementation of nextafterf that is intended to be
291 independent of the floating point format or its in memory representation.
292 This implementation works correctly with denormalized values. */
294 nextafterf(float x
, float y
)
296 /* This variable is marked volatile to avoid excess precision problems
297 on some platforms, including IA-32. */
298 volatile float delta
;
299 float absx
, denorm_min
;
301 if (isnan(x
) || isnan(y
))
306 return x
> 0 ? __FLT_MAX__
: - __FLT_MAX__
;
308 /* absx = fabsf (x); */
309 absx
= (x
< 0.0) ? -x
: x
;
311 /* __FLT_DENORM_MIN__ is non-zero iff the target supports denormals. */
312 if (__FLT_DENORM_MIN__
== 0.0f
)
313 denorm_min
= __FLT_MIN__
;
315 denorm_min
= __FLT_DENORM_MIN__
;
317 if (absx
< __FLT_MIN__
)
324 /* Discard the fraction from x. */
325 frac
= frexpf (absx
, &exp
);
326 delta
= scalbnf (0.5f
, exp
);
328 /* Scale x by the epsilon of the representation. By rights we should
329 have been able to combine this with scalbnf, but some targets don't
330 get that correct with denormals. */
331 delta
*= __FLT_EPSILON__
;
333 /* If we're going to be reducing the absolute value of X, and doing so
334 would reduce the exponent of X, then the delta to be applied is
335 one exponent smaller. */
336 if (frac
== 0.5f
&& (y
< x
) == (x
> 0))
339 /* If that underflows to zero, then we're back to the minimum. */
355 powf(float x
, float y
)
357 return (float) pow(x
, y
);
361 /* Note that if fpclassify is not defined, then NaN is not handled */
363 /* Algorithm by Steven G. Kargl. */
367 /* Round to nearest integral value. If the argument is halfway between two
368 integral values then round away from zero. */
395 #define HAVE_ROUNDF 1
396 /* Round to nearest integral value. If the argument is halfway between two
397 integral values then round away from zero. */
424 #define HAVE_LOG10L 1
425 /* log10 function for long double variables. The version provided here
426 reduces the argument until it fits into a double, then use log10. */
428 log10l(long double x
)
430 #if LDBL_MAX_EXP > DBL_MAX_EXP
435 if (x
> 0x1p
16383L) { p2_result
+= 16383; x
/= 0x1p
16383L; }
436 if (x
> 0x1p
8191L) { p2_result
+= 8191; x
/= 0x1p
8191L; }
437 if (x
> 0x1p
4095L) { p2_result
+= 4095; x
/= 0x1p
4095L; }
438 if (x
> 0x1p
2047L) { p2_result
+= 2047; x
/= 0x1p
2047L; }
439 if (x
> 0x1p
1023L) { p2_result
+= 1023; x
/= 0x1p
1023L; }
440 val
= log10 ((double) x
);
441 return (val
+ p2_result
* .30102999566398119521373889472449302L);
444 #if LDBL_MIN_EXP < DBL_MIN_EXP
449 if (x
< 0x1p
-16380L) { p2_result
+= 16380; x
/= 0x1p
-16380L; }
450 if (x
< 0x1p
-8189L) { p2_result
+= 8189; x
/= 0x1p
-8189L; }
451 if (x
< 0x1p
-4093L) { p2_result
+= 4093; x
/= 0x1p
-4093L; }
452 if (x
< 0x1p
-2045L) { p2_result
+= 2045; x
/= 0x1p
-2045L; }
453 if (x
< 0x1p
-1021L) { p2_result
+= 1021; x
/= 0x1p
-1021L; }
454 val
= fabs(log10 ((double) x
));
455 return (- val
- p2_result
* .30102999566398119521373889472449302L);
463 #if !defined(HAVE_CABSF)
466 cabsf (float complex z
)
468 return hypotf (REALPART (z
), IMAGPART (z
));
472 #if !defined(HAVE_CABS)
475 cabs (double complex z
)
477 return hypot (REALPART (z
), IMAGPART (z
));
481 #if !defined(HAVE_CABSL) && defined(HAVE_HYPOTL)
484 cabsl (long double complex z
)
486 return hypotl (REALPART (z
), IMAGPART (z
));
491 #if !defined(HAVE_CARGF)
494 cargf (float complex z
)
496 return atan2f (IMAGPART (z
), REALPART (z
));
500 #if !defined(HAVE_CARG)
503 carg (double complex z
)
505 return atan2 (IMAGPART (z
), REALPART (z
));
509 #if !defined(HAVE_CARGL) && defined(HAVE_ATAN2L)
512 cargl (long double complex z
)
514 return atan2l (IMAGPART (z
), REALPART (z
));
519 /* exp(z) = exp(a)*(cos(b) + i sin(b)) */
520 #if !defined(HAVE_CEXPF)
523 cexpf (float complex z
)
530 COMPLEX_ASSIGN (v
, cosf (b
), sinf (b
));
535 #if !defined(HAVE_CEXP)
538 cexp (double complex z
)
545 COMPLEX_ASSIGN (v
, cos (b
), sin (b
));
550 #if !defined(HAVE_CEXPL) && defined(HAVE_COSL) && defined(HAVE_SINL) && defined(EXPL)
553 cexpl (long double complex z
)
556 long double complex v
;
560 COMPLEX_ASSIGN (v
, cosl (b
), sinl (b
));
566 /* log(z) = log (cabs(z)) + i*carg(z) */
567 #if !defined(HAVE_CLOGF)
570 clogf (float complex z
)
574 COMPLEX_ASSIGN (v
, logf (cabsf (z
)), cargf (z
));
579 #if !defined(HAVE_CLOG)
582 clog (double complex z
)
586 COMPLEX_ASSIGN (v
, log (cabs (z
)), carg (z
));
591 #if !defined(HAVE_CLOGL) && defined(HAVE_LOGL) && defined(HAVE_CABSL) && defined(HAVE_CARGL)
594 clogl (long double complex z
)
596 long double complex v
;
598 COMPLEX_ASSIGN (v
, logl (cabsl (z
)), cargl (z
));
604 /* log10(z) = log10 (cabs(z)) + i*carg(z) */
605 #if !defined(HAVE_CLOG10F)
606 #define HAVE_CLOG10F 1
608 clog10f (float complex z
)
612 COMPLEX_ASSIGN (v
, log10f (cabsf (z
)), cargf (z
));
617 #if !defined(HAVE_CLOG10)
618 #define HAVE_CLOG10 1
620 clog10 (double complex z
)
624 COMPLEX_ASSIGN (v
, log10 (cabs (z
)), carg (z
));
629 #if !defined(HAVE_CLOG10L) && defined(HAVE_LOG10L) && defined(HAVE_CABSL) && defined(HAVE_CARGL)
630 #define HAVE_CLOG10L 1
632 clog10l (long double complex z
)
634 long double complex v
;
636 COMPLEX_ASSIGN (v
, log10l (cabsl (z
)), cargl (z
));
642 /* pow(base, power) = cexp (power * clog (base)) */
643 #if !defined(HAVE_CPOWF)
646 cpowf (float complex base
, float complex power
)
648 return cexpf (power
* clogf (base
));
652 #if !defined(HAVE_CPOW)
655 cpow (double complex base
, double complex power
)
657 return cexp (power
* clog (base
));
661 #if !defined(HAVE_CPOWL) && defined(HAVE_CEXPL) && defined(HAVE_CLOGL)
664 cpowl (long double complex base
, long double complex power
)
666 return cexpl (power
* clogl (base
));
671 /* sqrt(z). Algorithm pulled from glibc. */
672 #if !defined(HAVE_CSQRTF)
673 #define HAVE_CSQRTF 1
675 csqrtf (float complex z
)
686 COMPLEX_ASSIGN (v
, 0, copysignf (sqrtf (-re
), im
));
690 COMPLEX_ASSIGN (v
, fabsf (sqrtf (re
)), copysignf (0, im
));
697 r
= sqrtf (0.5 * fabsf (im
));
699 COMPLEX_ASSIGN (v
, r
, copysignf (r
, im
));
706 /* Use the identity 2 Re res Im res = Im x
707 to avoid cancellation error in d +/- Re x. */
710 r
= sqrtf (0.5 * d
+ 0.5 * re
);
715 s
= sqrtf (0.5 * d
- 0.5 * re
);
716 r
= fabsf ((0.5 * im
) / s
);
719 COMPLEX_ASSIGN (v
, r
, copysignf (s
, im
));
725 #if !defined(HAVE_CSQRT)
728 csqrt (double complex z
)
739 COMPLEX_ASSIGN (v
, 0, copysign (sqrt (-re
), im
));
743 COMPLEX_ASSIGN (v
, fabs (sqrt (re
)), copysign (0, im
));
750 r
= sqrt (0.5 * fabs (im
));
752 COMPLEX_ASSIGN (v
, r
, copysign (r
, im
));
759 /* Use the identity 2 Re res Im res = Im x
760 to avoid cancellation error in d +/- Re x. */
763 r
= sqrt (0.5 * d
+ 0.5 * re
);
768 s
= sqrt (0.5 * d
- 0.5 * re
);
769 r
= fabs ((0.5 * im
) / s
);
772 COMPLEX_ASSIGN (v
, r
, copysign (s
, im
));
778 #if !defined(HAVE_CSQRTL) && defined(HAVE_COPYSIGNL) && defined(HAVE_SQRTL) && defined(HAVE_FABSL) && defined(HAVE_HYPOTL)
779 #define HAVE_CSQRTL 1
781 csqrtl (long double complex z
)
784 long double complex v
;
792 COMPLEX_ASSIGN (v
, 0, copysignl (sqrtl (-re
), im
));
796 COMPLEX_ASSIGN (v
, fabsl (sqrtl (re
)), copysignl (0, im
));
803 r
= sqrtl (0.5 * fabsl (im
));
805 COMPLEX_ASSIGN (v
, copysignl (r
, im
), r
);
812 /* Use the identity 2 Re res Im res = Im x
813 to avoid cancellation error in d +/- Re x. */
816 r
= sqrtl (0.5 * d
+ 0.5 * re
);
821 s
= sqrtl (0.5 * d
- 0.5 * re
);
822 r
= fabsl ((0.5 * im
) / s
);
825 COMPLEX_ASSIGN (v
, r
, copysignl (s
, im
));
832 /* sinh(a + i b) = sinh(a) cos(b) + i cosh(a) sin(b) */
833 #if !defined(HAVE_CSINHF)
834 #define HAVE_CSINHF 1
836 csinhf (float complex a
)
843 COMPLEX_ASSIGN (v
, sinhf (r
) * cosf (i
), coshf (r
) * sinf (i
));
848 #if !defined(HAVE_CSINH)
851 csinh (double complex a
)
858 COMPLEX_ASSIGN (v
, sinh (r
) * cos (i
), cosh (r
) * sin (i
));
863 #if !defined(HAVE_CSINHL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
864 #define HAVE_CSINHL 1
866 csinhl (long double complex a
)
869 long double complex v
;
873 COMPLEX_ASSIGN (v
, sinhl (r
) * cosl (i
), coshl (r
) * sinl (i
));
879 /* cosh(a + i b) = cosh(a) cos(b) - i sinh(a) sin(b) */
880 #if !defined(HAVE_CCOSHF)
881 #define HAVE_CCOSHF 1
883 ccoshf (float complex a
)
890 COMPLEX_ASSIGN (v
, coshf (r
) * cosf (i
), - (sinhf (r
) * sinf (i
)));
895 #if !defined(HAVE_CCOSH)
898 ccosh (double complex a
)
905 COMPLEX_ASSIGN (v
, cosh (r
) * cos (i
), - (sinh (r
) * sin (i
)));
910 #if !defined(HAVE_CCOSHL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
911 #define HAVE_CCOSHL 1
913 ccoshl (long double complex a
)
916 long double complex v
;
920 COMPLEX_ASSIGN (v
, coshl (r
) * cosl (i
), - (sinhl (r
) * sinl (i
)));
926 /* tanh(a + i b) = (tanh(a) + i tan(b)) / (1 - i tanh(a) tan(b)) */
927 #if !defined(HAVE_CTANHF)
928 #define HAVE_CTANHF 1
930 ctanhf (float complex a
)
935 rt
= tanhf (REALPART (a
));
936 it
= tanf (IMAGPART (a
));
937 COMPLEX_ASSIGN (n
, rt
, it
);
938 COMPLEX_ASSIGN (d
, 1, - (rt
* it
));
944 #if !defined(HAVE_CTANH)
947 ctanh (double complex a
)
952 rt
= tanh (REALPART (a
));
953 it
= tan (IMAGPART (a
));
954 COMPLEX_ASSIGN (n
, rt
, it
);
955 COMPLEX_ASSIGN (d
, 1, - (rt
* it
));
961 #if !defined(HAVE_CTANHL) && defined(HAVE_TANL) && defined(HAVE_TANHL)
962 #define HAVE_CTANHL 1
964 ctanhl (long double complex a
)
967 long double complex n
, d
;
969 rt
= tanhl (REALPART (a
));
970 it
= tanl (IMAGPART (a
));
971 COMPLEX_ASSIGN (n
, rt
, it
);
972 COMPLEX_ASSIGN (d
, 1, - (rt
* it
));
979 /* sin(a + i b) = sin(a) cosh(b) + i cos(a) sinh(b) */
980 #if !defined(HAVE_CSINF)
983 csinf (float complex a
)
990 COMPLEX_ASSIGN (v
, sinf (r
) * coshf (i
), cosf (r
) * sinhf (i
));
995 #if !defined(HAVE_CSIN)
998 csin (double complex a
)
1005 COMPLEX_ASSIGN (v
, sin (r
) * cosh (i
), cos (r
) * sinh (i
));
1010 #if !defined(HAVE_CSINL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
1011 #define HAVE_CSINL 1
1013 csinl (long double complex a
)
1016 long double complex v
;
1020 COMPLEX_ASSIGN (v
, sinl (r
) * coshl (i
), cosl (r
) * sinhl (i
));
1026 /* cos(a + i b) = cos(a) cosh(b) - i sin(a) sinh(b) */
1027 #if !defined(HAVE_CCOSF)
1028 #define HAVE_CCOSF 1
1030 ccosf (float complex a
)
1037 COMPLEX_ASSIGN (v
, cosf (r
) * coshf (i
), - (sinf (r
) * sinhf (i
)));
1042 #if !defined(HAVE_CCOS)
1045 ccos (double complex a
)
1052 COMPLEX_ASSIGN (v
, cos (r
) * cosh (i
), - (sin (r
) * sinh (i
)));
1057 #if !defined(HAVE_CCOSL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
1058 #define HAVE_CCOSL 1
1060 ccosl (long double complex a
)
1063 long double complex v
;
1067 COMPLEX_ASSIGN (v
, cosl (r
) * coshl (i
), - (sinl (r
) * sinhl (i
)));
1073 /* tan(a + i b) = (tan(a) + i tanh(b)) / (1 - i tan(a) tanh(b)) */
1074 #if !defined(HAVE_CTANF)
1075 #define HAVE_CTANF 1
1077 ctanf (float complex a
)
1082 rt
= tanf (REALPART (a
));
1083 it
= tanhf (IMAGPART (a
));
1084 COMPLEX_ASSIGN (n
, rt
, it
);
1085 COMPLEX_ASSIGN (d
, 1, - (rt
* it
));
1091 #if !defined(HAVE_CTAN)
1094 ctan (double complex a
)
1097 double complex n
, d
;
1099 rt
= tan (REALPART (a
));
1100 it
= tanh (IMAGPART (a
));
1101 COMPLEX_ASSIGN (n
, rt
, it
);
1102 COMPLEX_ASSIGN (d
, 1, - (rt
* it
));
1108 #if !defined(HAVE_CTANL) && defined(HAVE_TANL) && defined(HAVE_TANHL)
1109 #define HAVE_CTANL 1
1111 ctanl (long double complex a
)
1114 long double complex n
, d
;
1116 rt
= tanl (REALPART (a
));
1117 it
= tanhl (IMAGPART (a
));
1118 COMPLEX_ASSIGN (n
, rt
, it
);
1119 COMPLEX_ASSIGN (d
, 1, - (rt
* it
));