]> git.ipfire.org Git - thirdparty/gcc.git/blame - libgfortran/intrinsics/c99_functions.c
Update copyright years in libgfortran.
[thirdparty/gcc.git] / libgfortran / intrinsics / c99_functions.c
CommitLineData
a2a2059f 1/* Implementation of various C99 functions
e3c063ce 2 Copyright (C) 2004-2013 Free Software Foundation, Inc.
a2a2059f
BD
3
4This file is part of the GNU Fortran 95 runtime library (libgfortran).
5
6Libgfortran is free software; you can redistribute it and/or
57dea9f6 7modify it under the terms of the GNU General Public
a2a2059f 8License as published by the Free Software Foundation; either
748086b7 9version 3 of the License, or (at your option) any later version.
a2a2059f
BD
10
11Libgfortran is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
57dea9f6 14GNU General Public License for more details.
a2a2059f 15
748086b7
JJ
16Under Section 7 of GPL version 3, you are granted additional
17permissions described in the GCC Runtime Library Exception, version
183.1, as published by the Free Software Foundation.
19
20You should have received a copy of the GNU General Public License and
21a copy of the GCC Runtime Library Exception along with this program;
22see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23<http://www.gnu.org/licenses/>. */
a2a2059f
BD
24
25#include "config.h"
1409cd0b
FXC
26
27#define C99_PROTOS_H WE_DONT_WANT_PROTOS_NOW
a2a2059f
BD
28#include "libgfortran.h"
29
d08d4988
TB
30/* On a C99 system "I" (with I*I = -1) should be defined in complex.h;
31 if not, we define a fallback version here. */
32#ifndef I
33# if defined(_Imaginary_I)
34# define I _Imaginary_I
35# elif defined(_Complex_I)
36# define I _Complex_I
37# else
38# define I (1.0fi)
39# endif
40#endif
edf8dc34 41
d08d4988
TB
42/* Prototypes are included to silence -Wstrict-prototypes
43 -Wmissing-prototypes. */
edf8dc34 44
7afebb02
FXC
45
46/* Wrappers for systems without the various C99 single precision Bessel
47 functions. */
48
49#if defined(HAVE_J0) && ! defined(HAVE_J0F)
50#define HAVE_J0F 1
d08d4988 51float j0f (float);
7afebb02
FXC
52
53float
54j0f (float x)
55{
56 return (float) j0 ((double) x);
57}
58#endif
59
60#if defined(HAVE_J1) && !defined(HAVE_J1F)
61#define HAVE_J1F 1
d08d4988 62float j1f (float);
7afebb02
FXC
63
64float j1f (float x)
65{
66 return (float) j1 ((double) x);
67}
68#endif
69
70#if defined(HAVE_JN) && !defined(HAVE_JNF)
71#define HAVE_JNF 1
d08d4988 72float jnf (int, float);
7afebb02
FXC
73
74float
75jnf (int n, float x)
76{
77 return (float) jn (n, (double) x);
78}
79#endif
80
81#if defined(HAVE_Y0) && !defined(HAVE_Y0F)
82#define HAVE_Y0F 1
d08d4988 83float y0f (float);
7afebb02
FXC
84
85float
86y0f (float x)
87{
88 return (float) y0 ((double) x);
89}
90#endif
91
92#if defined(HAVE_Y1) && !defined(HAVE_Y1F)
93#define HAVE_Y1F 1
d08d4988 94float y1f (float);
7afebb02
FXC
95
96float
97y1f (float x)
98{
99 return (float) y1 ((double) x);
100}
101#endif
102
103#if defined(HAVE_YN) && !defined(HAVE_YNF)
104#define HAVE_YNF 1
d08d4988 105float ynf (int, float);
7afebb02
FXC
106
107float
108ynf (int n, float x)
109{
110 return (float) yn (n, (double) x);
111}
112#endif
113
114
115/* Wrappers for systems without the C99 erff() and erfcf() functions. */
116
117#if defined(HAVE_ERF) && !defined(HAVE_ERFF)
118#define HAVE_ERFF 1
d08d4988 119float erff (float);
7afebb02
FXC
120
121float
122erff (float x)
123{
124 return (float) erf ((double) x);
125}
126#endif
127
128#if defined(HAVE_ERFC) && !defined(HAVE_ERFCF)
129#define HAVE_ERFCF 1
d08d4988 130float erfcf (float);
7afebb02
FXC
131
132float
133erfcf (float x)
134{
135 return (float) erfc ((double) x);
136}
137#endif
138
139
453310d8 140#ifndef HAVE_ACOSF
2cdc88b6 141#define HAVE_ACOSF 1
d08d4988
TB
142float acosf (float x);
143
453310d8 144float
d08d4988 145acosf (float x)
453310d8 146{
d08d4988 147 return (float) acos (x);
453310d8
RS
148}
149#endif
150
456d9b17 151#if HAVE_ACOSH && !HAVE_ACOSHF
d08d4988
TB
152float acoshf (float x);
153
456d9b17
FXC
154float
155acoshf (float x)
156{
157 return (float) acosh ((double) x);
158}
159#endif
160
453310d8 161#ifndef HAVE_ASINF
2cdc88b6 162#define HAVE_ASINF 1
d08d4988
TB
163float asinf (float x);
164
453310d8 165float
d08d4988 166asinf (float x)
453310d8 167{
d08d4988 168 return (float) asin (x);
453310d8
RS
169}
170#endif
171
456d9b17 172#if HAVE_ASINH && !HAVE_ASINHF
d08d4988
TB
173float asinhf (float x);
174
456d9b17
FXC
175float
176asinhf (float x)
177{
178 return (float) asinh ((double) x);
179}
180#endif
181
453310d8 182#ifndef HAVE_ATAN2F
2cdc88b6 183#define HAVE_ATAN2F 1
d08d4988
TB
184float atan2f (float y, float x);
185
453310d8 186float
d08d4988 187atan2f (float y, float x)
453310d8 188{
d08d4988 189 return (float) atan2 (y, x);
453310d8
RS
190}
191#endif
192
193#ifndef HAVE_ATANF
2cdc88b6 194#define HAVE_ATANF 1
d08d4988
TB
195float atanf (float x);
196
453310d8 197float
d08d4988 198atanf (float x)
453310d8 199{
d08d4988 200 return (float) atan (x);
453310d8
RS
201}
202#endif
203
456d9b17 204#if HAVE_ATANH && !HAVE_ATANHF
d08d4988
TB
205float atanhf (float x);
206
456d9b17
FXC
207float
208atanhf (float x)
209{
210 return (float) atanh ((double) x);
211}
212#endif
213
453310d8 214#ifndef HAVE_CEILF
2cdc88b6 215#define HAVE_CEILF 1
d08d4988
TB
216float ceilf (float x);
217
453310d8 218float
d08d4988 219ceilf (float x)
453310d8 220{
d08d4988 221 return (float) ceil (x);
453310d8
RS
222}
223#endif
224
225#ifndef HAVE_COPYSIGNF
2cdc88b6 226#define HAVE_COPYSIGNF 1
d08d4988
TB
227float copysignf (float x, float y);
228
453310d8 229float
d08d4988 230copysignf (float x, float y)
453310d8 231{
d08d4988 232 return (float) copysign (x, y);
453310d8
RS
233}
234#endif
235
236#ifndef HAVE_COSF
2cdc88b6 237#define HAVE_COSF 1
d08d4988
TB
238float cosf (float x);
239
453310d8 240float
d08d4988 241cosf (float x)
453310d8 242{
d08d4988 243 return (float) cos (x);
453310d8
RS
244}
245#endif
246
247#ifndef HAVE_COSHF
2cdc88b6 248#define HAVE_COSHF 1
d08d4988
TB
249float coshf (float x);
250
453310d8 251float
d08d4988 252coshf (float x)
453310d8 253{
d08d4988 254 return (float) cosh (x);
453310d8
RS
255}
256#endif
257
258#ifndef HAVE_EXPF
2cdc88b6 259#define HAVE_EXPF 1
d08d4988
TB
260float expf (float x);
261
453310d8 262float
d08d4988 263expf (float x)
453310d8 264{
d08d4988 265 return (float) exp (x);
453310d8
RS
266}
267#endif
268
6e4d9244 269#ifndef HAVE_FABSF
2cdc88b6 270#define HAVE_FABSF 1
d08d4988
TB
271float fabsf (float x);
272
6e4d9244 273float
d08d4988 274fabsf (float x)
6e4d9244 275{
d08d4988 276 return (float) fabs (x);
6e4d9244
EB
277}
278#endif
279
453310d8 280#ifndef HAVE_FLOORF
2cdc88b6 281#define HAVE_FLOORF 1
d08d4988
TB
282float floorf (float x);
283
453310d8 284float
d08d4988 285floorf (float x)
453310d8 286{
d08d4988 287 return (float) floor (x);
453310d8
RS
288}
289#endif
290
eb647f7d
FXC
291#ifndef HAVE_FMODF
292#define HAVE_FMODF 1
d08d4988
TB
293float fmodf (float x, float y);
294
eb647f7d
FXC
295float
296fmodf (float x, float y)
297{
298 return (float) fmod (x, y);
299}
300#endif
301
453310d8 302#ifndef HAVE_FREXPF
2cdc88b6 303#define HAVE_FREXPF 1
d08d4988
TB
304float frexpf (float x, int *exp);
305
453310d8 306float
d08d4988 307frexpf (float x, int *exp)
453310d8 308{
d08d4988 309 return (float) frexp (x, exp);
453310d8
RS
310}
311#endif
312
313#ifndef HAVE_HYPOTF
2cdc88b6 314#define HAVE_HYPOTF 1
d08d4988
TB
315float hypotf (float x, float y);
316
453310d8 317float
d08d4988 318hypotf (float x, float y)
453310d8 319{
d08d4988 320 return (float) hypot (x, y);
453310d8
RS
321}
322#endif
323
324#ifndef HAVE_LOGF
2cdc88b6 325#define HAVE_LOGF 1
d08d4988
TB
326float logf (float x);
327
453310d8 328float
d08d4988 329logf (float x)
453310d8 330{
d08d4988 331 return (float) log (x);
453310d8
RS
332}
333#endif
334
335#ifndef HAVE_LOG10F
2cdc88b6 336#define HAVE_LOG10F 1
d08d4988
TB
337float log10f (float x);
338
453310d8 339float
d08d4988 340log10f (float x)
453310d8 341{
d08d4988 342 return (float) log10 (x);
453310d8
RS
343}
344#endif
345
ae973d6a 346#ifndef HAVE_SCALBN
2cdc88b6 347#define HAVE_SCALBN 1
d08d4988
TB
348double scalbn (double x, int y);
349
ae973d6a 350double
d08d4988 351scalbn (double x, int y)
ae973d6a 352{
b65d72ab
FXC
353#if (FLT_RADIX == 2) && defined(HAVE_LDEXP)
354 return ldexp (x, y);
355#else
d08d4988 356 return x * pow (FLT_RADIX, y);
b65d72ab 357#endif
ae973d6a
FXC
358}
359#endif
360
453310d8 361#ifndef HAVE_SCALBNF
2cdc88b6 362#define HAVE_SCALBNF 1
d08d4988
TB
363float scalbnf (float x, int y);
364
453310d8 365float
d08d4988 366scalbnf (float x, int y)
453310d8 367{
d08d4988 368 return (float) scalbn (x, y);
453310d8
RS
369}
370#endif
371
372#ifndef HAVE_SINF
2cdc88b6 373#define HAVE_SINF 1
d08d4988
TB
374float sinf (float x);
375
453310d8 376float
d08d4988 377sinf (float x)
453310d8 378{
d08d4988 379 return (float) sin (x);
453310d8
RS
380}
381#endif
382
383#ifndef HAVE_SINHF
2cdc88b6 384#define HAVE_SINHF 1
d08d4988
TB
385float sinhf (float x);
386
453310d8 387float
d08d4988 388sinhf (float x)
453310d8 389{
d08d4988 390 return (float) sinh (x);
453310d8
RS
391}
392#endif
393
394#ifndef HAVE_SQRTF
2cdc88b6 395#define HAVE_SQRTF 1
d08d4988
TB
396float sqrtf (float x);
397
453310d8 398float
d08d4988 399sqrtf (float x)
453310d8 400{
d08d4988 401 return (float) sqrt (x);
453310d8
RS
402}
403#endif
404
405#ifndef HAVE_TANF
2cdc88b6 406#define HAVE_TANF 1
d08d4988
TB
407float tanf (float x);
408
453310d8 409float
d08d4988 410tanf (float x)
453310d8 411{
d08d4988 412 return (float) tan (x);
453310d8
RS
413}
414#endif
415
416#ifndef HAVE_TANHF
2cdc88b6 417#define HAVE_TANHF 1
d08d4988
TB
418float tanhf (float x);
419
453310d8 420float
d08d4988 421tanhf (float x)
453310d8 422{
d08d4988 423 return (float) tanh (x);
453310d8
RS
424}
425#endif
426
69a2d125 427#ifndef HAVE_TRUNC
2cdc88b6 428#define HAVE_TRUNC 1
d08d4988
TB
429double trunc (double x);
430
69a2d125 431double
d08d4988 432trunc (double x)
69a2d125
EB
433{
434 if (!isfinite (x))
435 return x;
436
437 if (x < 0.0)
438 return - floor (-x);
439 else
440 return floor (x);
441}
442#endif
443
444#ifndef HAVE_TRUNCF
2cdc88b6 445#define HAVE_TRUNCF 1
d08d4988
TB
446float truncf (float x);
447
69a2d125 448float
d08d4988 449truncf (float x)
69a2d125
EB
450{
451 return (float) trunc (x);
452}
453#endif
454
453310d8 455#ifndef HAVE_NEXTAFTERF
2cdc88b6 456#define HAVE_NEXTAFTERF 1
453310d8
RS
457/* This is a portable implementation of nextafterf that is intended to be
458 independent of the floating point format or its in memory representation.
067a5735 459 This implementation works correctly with denormalized values. */
d08d4988
TB
460float nextafterf (float x, float y);
461
453310d8 462float
d08d4988 463nextafterf (float x, float y)
453310d8 464{
067a5735
RS
465 /* This variable is marked volatile to avoid excess precision problems
466 on some platforms, including IA-32. */
467 volatile float delta;
468 float absx, denorm_min;
453310d8 469
d08d4988 470 if (isnan (x) || isnan (y))
067a5735 471 return x + y;
453310d8
RS
472 if (x == y)
473 return x;
74421469
EB
474 if (!isfinite (x))
475 return x > 0 ? __FLT_MAX__ : - __FLT_MAX__;
453310d8 476
067a5735
RS
477 /* absx = fabsf (x); */
478 absx = (x < 0.0) ? -x : x;
453310d8 479
067a5735
RS
480 /* __FLT_DENORM_MIN__ is non-zero iff the target supports denormals. */
481 if (__FLT_DENORM_MIN__ == 0.0f)
482 denorm_min = __FLT_MIN__;
483 else
484 denorm_min = __FLT_DENORM_MIN__;
485
486 if (absx < __FLT_MIN__)
487 delta = denorm_min;
453310d8
RS
488 else
489 {
067a5735
RS
490 float frac;
491 int exp;
492
493 /* Discard the fraction from x. */
494 frac = frexpf (absx, &exp);
495 delta = scalbnf (0.5f, exp);
496
497 /* Scale x by the epsilon of the representation. By rights we should
498 have been able to combine this with scalbnf, but some targets don't
499 get that correct with denormals. */
500 delta *= __FLT_EPSILON__;
501
502 /* If we're going to be reducing the absolute value of X, and doing so
503 would reduce the exponent of X, then the delta to be applied is
504 one exponent smaller. */
505 if (frac == 0.5f && (y < x) == (x > 0))
506 delta *= 0.5f;
507
508 /* If that underflows to zero, then we're back to the minimum. */
509 if (delta == 0.0f)
510 delta = denorm_min;
453310d8 511 }
067a5735
RS
512
513 if (y < x)
514 delta = -delta;
515
516 return x + delta;
453310d8
RS
517}
518#endif
519
bf4d99cf 520
c0c3c409 521#if !defined(HAVE_POWF) || defined(HAVE_BROKEN_POWF)
bf4d99cf 522#ifndef HAVE_POWF
2cdc88b6 523#define HAVE_POWF 1
c0c3c409 524#endif
d08d4988
TB
525float powf (float x, float y);
526
bf4d99cf 527float
d08d4988 528powf (float x, float y)
bf4d99cf 529{
d08d4988 530 return (float) pow (x, y);
bf4d99cf
TS
531}
532#endif
533
bc20e36d 534
287188ea
FXC
535#ifndef HAVE_ROUND
536#define HAVE_ROUND 1
537/* Round to nearest integral value. If the argument is halfway between two
538 integral values then round away from zero. */
539double round (double x);
540
541double
542round (double x)
543{
544 double t;
545 if (!isfinite (x))
546 return (x);
547
548 if (x >= 0.0)
549 {
550 t = floor (x);
551 if (t - x <= -0.5)
552 t += 1.0;
553 return (t);
554 }
555 else
556 {
557 t = floor (-x);
558 if (t + x <= -0.5)
559 t += 1.0;
560 return (-t);
561 }
562}
563#endif
564
565
a2a2059f
BD
566/* Algorithm by Steven G. Kargl. */
567
c120ef14 568#if !defined(HAVE_ROUNDL)
94f548c2 569#define HAVE_ROUNDL 1
d08d4988
TB
570long double roundl (long double x);
571
c120ef14 572#if defined(HAVE_CEILL)
94f548c2
FXC
573/* Round to nearest integral value. If the argument is halfway between two
574 integral values then round away from zero. */
575
576long double
d08d4988 577roundl (long double x)
94f548c2
FXC
578{
579 long double t;
580 if (!isfinite (x))
581 return (x);
582
583 if (x >= 0.0)
584 {
d08d4988 585 t = ceill (x);
94f548c2
FXC
586 if (t - x > 0.5)
587 t -= 1.0;
588 return (t);
589 }
590 else
591 {
d08d4988 592 t = ceill (-x);
94f548c2
FXC
593 if (t + x > 0.5)
594 t -= 1.0;
595 return (-t);
596 }
597}
c120ef14
FXC
598#else
599
600/* Poor version of roundl for system that don't have ceill. */
601long double
d08d4988 602roundl (long double x)
c120ef14
FXC
603{
604 if (x > DBL_MAX || x < -DBL_MAX)
605 {
606#ifdef HAVE_NEXTAFTERL
1c4bc9ca 607 long double prechalf = nextafterl (0.5L, LDBL_MAX);
c120ef14
FXC
608#else
609 static long double prechalf = 0.5L;
610#endif
611 return (GFC_INTEGER_LARGEST) (x + (x > 0 ? prechalf : -prechalf));
612 }
613 else
614 /* Use round(). */
d08d4988 615 return round ((double) x);
c120ef14
FXC
616}
617
618#endif
94f548c2
FXC
619#endif
620
a2a2059f 621#ifndef HAVE_ROUNDF
2cdc88b6 622#define HAVE_ROUNDF 1
a2a2059f
BD
623/* Round to nearest integral value. If the argument is halfway between two
624 integral values then round away from zero. */
d08d4988 625float roundf (float x);
a2a2059f
BD
626
627float
d08d4988 628roundf (float x)
a2a2059f
BD
629{
630 float t;
118ea208 631 if (!isfinite (x))
a2a2059f
BD
632 return (x);
633
634 if (x >= 0.0)
635 {
d08d4988 636 t = floorf (x);
63f90eb7
JDA
637 if (t - x <= -0.5)
638 t += 1.0;
a2a2059f
BD
639 return (t);
640 }
641 else
642 {
d08d4988 643 t = floorf (-x);
63f90eb7
JDA
644 if (t + x <= -0.5)
645 t += 1.0;
a2a2059f
BD
646 return (-t);
647 }
648}
649#endif
32aa3bff 650
94f548c2
FXC
651
652/* lround{f,,l} and llround{f,,l} functions. */
653
654#if !defined(HAVE_LROUNDF) && defined(HAVE_ROUNDF)
655#define HAVE_LROUNDF 1
d08d4988
TB
656long int lroundf (float x);
657
94f548c2
FXC
658long int
659lroundf (float x)
660{
661 return (long int) roundf (x);
662}
663#endif
664
665#if !defined(HAVE_LROUND) && defined(HAVE_ROUND)
666#define HAVE_LROUND 1
d08d4988
TB
667long int lround (double x);
668
94f548c2
FXC
669long int
670lround (double x)
671{
672 return (long int) round (x);
673}
674#endif
675
676#if !defined(HAVE_LROUNDL) && defined(HAVE_ROUNDL)
677#define HAVE_LROUNDL 1
d08d4988
TB
678long int lroundl (long double x);
679
94f548c2
FXC
680long int
681lroundl (long double x)
682{
683 return (long long int) roundl (x);
684}
685#endif
686
687#if !defined(HAVE_LLROUNDF) && defined(HAVE_ROUNDF)
688#define HAVE_LLROUNDF 1
d08d4988
TB
689long long int llroundf (float x);
690
94f548c2
FXC
691long long int
692llroundf (float x)
693{
694 return (long long int) roundf (x);
695}
696#endif
697
698#if !defined(HAVE_LLROUND) && defined(HAVE_ROUND)
699#define HAVE_LLROUND 1
d08d4988
TB
700long long int llround (double x);
701
94f548c2
FXC
702long long int
703llround (double x)
704{
705 return (long long int) round (x);
706}
707#endif
708
709#if !defined(HAVE_LLROUNDL) && defined(HAVE_ROUNDL)
710#define HAVE_LLROUNDL 1
d08d4988
TB
711long long int llroundl (long double x);
712
94f548c2
FXC
713long long int
714llroundl (long double x)
715{
716 return (long long int) roundl (x);
717}
718#endif
719
720
32aa3bff 721#ifndef HAVE_LOG10L
2cdc88b6 722#define HAVE_LOG10L 1
32aa3bff
FXC
723/* log10 function for long double variables. The version provided here
724 reduces the argument until it fits into a double, then use log10. */
d08d4988
TB
725long double log10l (long double x);
726
32aa3bff 727long double
d08d4988 728log10l (long double x)
32aa3bff
FXC
729{
730#if LDBL_MAX_EXP > DBL_MAX_EXP
731 if (x > DBL_MAX)
732 {
733 double val;
734 int p2_result = 0;
735 if (x > 0x1p16383L) { p2_result += 16383; x /= 0x1p16383L; }
736 if (x > 0x1p8191L) { p2_result += 8191; x /= 0x1p8191L; }
737 if (x > 0x1p4095L) { p2_result += 4095; x /= 0x1p4095L; }
738 if (x > 0x1p2047L) { p2_result += 2047; x /= 0x1p2047L; }
739 if (x > 0x1p1023L) { p2_result += 1023; x /= 0x1p1023L; }
740 val = log10 ((double) x);
741 return (val + p2_result * .30102999566398119521373889472449302L);
742 }
743#endif
744#if LDBL_MIN_EXP < DBL_MIN_EXP
745 if (x < DBL_MIN)
746 {
747 double val;
748 int p2_result = 0;
749 if (x < 0x1p-16380L) { p2_result += 16380; x /= 0x1p-16380L; }
750 if (x < 0x1p-8189L) { p2_result += 8189; x /= 0x1p-8189L; }
751 if (x < 0x1p-4093L) { p2_result += 4093; x /= 0x1p-4093L; }
752 if (x < 0x1p-2045L) { p2_result += 2045; x /= 0x1p-2045L; }
753 if (x < 0x1p-1021L) { p2_result += 1021; x /= 0x1p-1021L; }
d08d4988 754 val = fabs (log10 ((double) x));
32aa3bff
FXC
755 return (- val - p2_result * .30102999566398119521373889472449302L);
756 }
757#endif
758 return log10 (x);
759}
760#endif
1409cd0b
FXC
761
762
eb647f7d
FXC
763#ifndef HAVE_FLOORL
764#define HAVE_FLOORL 1
d08d4988
TB
765long double floorl (long double x);
766
eb647f7d
FXC
767long double
768floorl (long double x)
769{
770 /* Zero, possibly signed. */
771 if (x == 0)
772 return x;
773
774 /* Large magnitude. */
775 if (x > DBL_MAX || x < (-DBL_MAX))
776 return x;
777
778 /* Small positive values. */
779 if (x >= 0 && x < DBL_MIN)
780 return 0;
781
782 /* Small negative values. */
783 if (x < 0 && x > (-DBL_MIN))
784 return -1;
785
786 return floor (x);
787}
788#endif
789
790
791#ifndef HAVE_FMODL
792#define HAVE_FMODL 1
d08d4988
TB
793long double fmodl (long double x, long double y);
794
eb647f7d
FXC
795long double
796fmodl (long double x, long double y)
797{
798 if (y == 0.0L)
799 return 0.0L;
800
801 /* Need to check that the result has the same sign as x and magnitude
802 less than the magnitude of y. */
803 return x - floorl (x / y) * y;
804}
805#endif
806
807
1409cd0b 808#if !defined(HAVE_CABSF)
2cdc88b6 809#define HAVE_CABSF 1
d08d4988
TB
810float cabsf (float complex z);
811
1409cd0b
FXC
812float
813cabsf (float complex z)
814{
815 return hypotf (REALPART (z), IMAGPART (z));
816}
817#endif
818
819#if !defined(HAVE_CABS)
2cdc88b6 820#define HAVE_CABS 1
d08d4988
TB
821double cabs (double complex z);
822
1409cd0b
FXC
823double
824cabs (double complex z)
825{
826 return hypot (REALPART (z), IMAGPART (z));
827}
828#endif
829
830#if !defined(HAVE_CABSL) && defined(HAVE_HYPOTL)
2cdc88b6 831#define HAVE_CABSL 1
d08d4988
TB
832long double cabsl (long double complex z);
833
1409cd0b
FXC
834long double
835cabsl (long double complex z)
836{
837 return hypotl (REALPART (z), IMAGPART (z));
838}
839#endif
840
841
842#if !defined(HAVE_CARGF)
2cdc88b6 843#define HAVE_CARGF 1
d08d4988
TB
844float cargf (float complex z);
845
1409cd0b
FXC
846float
847cargf (float complex z)
848{
849 return atan2f (IMAGPART (z), REALPART (z));
850}
851#endif
852
853#if !defined(HAVE_CARG)
2cdc88b6 854#define HAVE_CARG 1
d08d4988
TB
855double carg (double complex z);
856
1409cd0b
FXC
857double
858carg (double complex z)
859{
860 return atan2 (IMAGPART (z), REALPART (z));
861}
862#endif
863
864#if !defined(HAVE_CARGL) && defined(HAVE_ATAN2L)
2cdc88b6 865#define HAVE_CARGL 1
d08d4988
TB
866long double cargl (long double complex z);
867
1409cd0b
FXC
868long double
869cargl (long double complex z)
870{
871 return atan2l (IMAGPART (z), REALPART (z));
872}
873#endif
874
875
876/* exp(z) = exp(a)*(cos(b) + i sin(b)) */
877#if !defined(HAVE_CEXPF)
2cdc88b6 878#define HAVE_CEXPF 1
d08d4988
TB
879float complex cexpf (float complex z);
880
1409cd0b
FXC
881float complex
882cexpf (float complex z)
883{
884 float a, b;
885 float complex v;
886
887 a = REALPART (z);
888 b = IMAGPART (z);
889 COMPLEX_ASSIGN (v, cosf (b), sinf (b));
890 return expf (a) * v;
891}
892#endif
893
894#if !defined(HAVE_CEXP)
2cdc88b6 895#define HAVE_CEXP 1
d08d4988
TB
896double complex cexp (double complex z);
897
1409cd0b
FXC
898double complex
899cexp (double complex z)
900{
901 double a, b;
902 double complex v;
903
904 a = REALPART (z);
905 b = IMAGPART (z);
906 COMPLEX_ASSIGN (v, cos (b), sin (b));
907 return exp (a) * v;
908}
909#endif
910
911#if !defined(HAVE_CEXPL) && defined(HAVE_COSL) && defined(HAVE_SINL) && defined(EXPL)
2cdc88b6 912#define HAVE_CEXPL 1
d08d4988
TB
913long double complex cexpl (long double complex z);
914
1409cd0b
FXC
915long double complex
916cexpl (long double complex z)
917{
918 long double a, b;
919 long double complex v;
920
921 a = REALPART (z);
922 b = IMAGPART (z);
923 COMPLEX_ASSIGN (v, cosl (b), sinl (b));
924 return expl (a) * v;
925}
926#endif
927
928
929/* log(z) = log (cabs(z)) + i*carg(z) */
930#if !defined(HAVE_CLOGF)
2cdc88b6 931#define HAVE_CLOGF 1
d08d4988
TB
932float complex clogf (float complex z);
933
1409cd0b
FXC
934float complex
935clogf (float complex z)
936{
937 float complex v;
938
939 COMPLEX_ASSIGN (v, logf (cabsf (z)), cargf (z));
940 return v;
941}
942#endif
943
944#if !defined(HAVE_CLOG)
2cdc88b6 945#define HAVE_CLOG 1
d08d4988
TB
946double complex clog (double complex z);
947
1409cd0b
FXC
948double complex
949clog (double complex z)
950{
951 double complex v;
952
953 COMPLEX_ASSIGN (v, log (cabs (z)), carg (z));
954 return v;
955}
956#endif
957
958#if !defined(HAVE_CLOGL) && defined(HAVE_LOGL) && defined(HAVE_CABSL) && defined(HAVE_CARGL)
2cdc88b6 959#define HAVE_CLOGL 1
d08d4988
TB
960long double complex clogl (long double complex z);
961
1409cd0b
FXC
962long double complex
963clogl (long double complex z)
964{
965 long double complex v;
966
967 COMPLEX_ASSIGN (v, logl (cabsl (z)), cargl (z));
968 return v;
969}
970#endif
971
972
973/* log10(z) = log10 (cabs(z)) + i*carg(z) */
974#if !defined(HAVE_CLOG10F)
2cdc88b6 975#define HAVE_CLOG10F 1
d08d4988
TB
976float complex clog10f (float complex z);
977
1409cd0b
FXC
978float complex
979clog10f (float complex z)
980{
981 float complex v;
982
983 COMPLEX_ASSIGN (v, log10f (cabsf (z)), cargf (z));
984 return v;
985}
986#endif
987
988#if !defined(HAVE_CLOG10)
2cdc88b6 989#define HAVE_CLOG10 1
d08d4988
TB
990double complex clog10 (double complex z);
991
1409cd0b
FXC
992double complex
993clog10 (double complex z)
994{
995 double complex v;
996
997 COMPLEX_ASSIGN (v, log10 (cabs (z)), carg (z));
998 return v;
999}
1000#endif
1001
1002#if !defined(HAVE_CLOG10L) && defined(HAVE_LOG10L) && defined(HAVE_CABSL) && defined(HAVE_CARGL)
2cdc88b6 1003#define HAVE_CLOG10L 1
d08d4988
TB
1004long double complex clog10l (long double complex z);
1005
1409cd0b
FXC
1006long double complex
1007clog10l (long double complex z)
1008{
1009 long double complex v;
1010
1011 COMPLEX_ASSIGN (v, log10l (cabsl (z)), cargl (z));
1012 return v;
1013}
1014#endif
1015
1016
1017/* pow(base, power) = cexp (power * clog (base)) */
1018#if !defined(HAVE_CPOWF)
2cdc88b6 1019#define HAVE_CPOWF 1
d08d4988
TB
1020float complex cpowf (float complex base, float complex power);
1021
1409cd0b
FXC
1022float complex
1023cpowf (float complex base, float complex power)
1024{
1025 return cexpf (power * clogf (base));
1026}
1027#endif
1028
1029#if !defined(HAVE_CPOW)
2cdc88b6 1030#define HAVE_CPOW 1
d08d4988
TB
1031double complex cpow (double complex base, double complex power);
1032
1409cd0b
FXC
1033double complex
1034cpow (double complex base, double complex power)
1035{
1036 return cexp (power * clog (base));
1037}
1038#endif
1039
1040#if !defined(HAVE_CPOWL) && defined(HAVE_CEXPL) && defined(HAVE_CLOGL)
2cdc88b6 1041#define HAVE_CPOWL 1
d08d4988
TB
1042long double complex cpowl (long double complex base, long double complex power);
1043
1409cd0b
FXC
1044long double complex
1045cpowl (long double complex base, long double complex power)
1046{
1047 return cexpl (power * clogl (base));
1048}
1049#endif
1050
1051
1052/* sqrt(z). Algorithm pulled from glibc. */
1053#if !defined(HAVE_CSQRTF)
2cdc88b6 1054#define HAVE_CSQRTF 1
d08d4988
TB
1055float complex csqrtf (float complex z);
1056
1409cd0b
FXC
1057float complex
1058csqrtf (float complex z)
1059{
1060 float re, im;
1061 float complex v;
1062
1063 re = REALPART (z);
1064 im = IMAGPART (z);
1065 if (im == 0)
1066 {
1067 if (re < 0)
1068 {
1069 COMPLEX_ASSIGN (v, 0, copysignf (sqrtf (-re), im));
1070 }
1071 else
1072 {
1073 COMPLEX_ASSIGN (v, fabsf (sqrtf (re)), copysignf (0, im));
1074 }
1075 }
1076 else if (re == 0)
1077 {
1078 float r;
1079
1080 r = sqrtf (0.5 * fabsf (im));
1081
a2694f68 1082 COMPLEX_ASSIGN (v, r, copysignf (r, im));
1409cd0b
FXC
1083 }
1084 else
1085 {
1086 float d, r, s;
1087
1088 d = hypotf (re, im);
1089 /* Use the identity 2 Re res Im res = Im x
1090 to avoid cancellation error in d +/- Re x. */
1091 if (re > 0)
1092 {
1093 r = sqrtf (0.5 * d + 0.5 * re);
1094 s = (0.5 * im) / r;
1095 }
1096 else
1097 {
1098 s = sqrtf (0.5 * d - 0.5 * re);
1099 r = fabsf ((0.5 * im) / s);
1100 }
1101
1102 COMPLEX_ASSIGN (v, r, copysignf (s, im));
1103 }
1104 return v;
1105}
1106#endif
1107
1108#if !defined(HAVE_CSQRT)
2cdc88b6 1109#define HAVE_CSQRT 1
d08d4988
TB
1110double complex csqrt (double complex z);
1111
1409cd0b
FXC
1112double complex
1113csqrt (double complex z)
1114{
1115 double re, im;
1116 double complex v;
1117
1118 re = REALPART (z);
1119 im = IMAGPART (z);
1120 if (im == 0)
1121 {
1122 if (re < 0)
1123 {
1124 COMPLEX_ASSIGN (v, 0, copysign (sqrt (-re), im));
1125 }
1126 else
1127 {
1128 COMPLEX_ASSIGN (v, fabs (sqrt (re)), copysign (0, im));
1129 }
1130 }
1131 else if (re == 0)
1132 {
1133 double r;
1134
1135 r = sqrt (0.5 * fabs (im));
1136
a2694f68 1137 COMPLEX_ASSIGN (v, r, copysign (r, im));
1409cd0b
FXC
1138 }
1139 else
1140 {
1141 double d, r, s;
1142
1143 d = hypot (re, im);
1144 /* Use the identity 2 Re res Im res = Im x
1145 to avoid cancellation error in d +/- Re x. */
1146 if (re > 0)
1147 {
1148 r = sqrt (0.5 * d + 0.5 * re);
1149 s = (0.5 * im) / r;
1150 }
1151 else
1152 {
1153 s = sqrt (0.5 * d - 0.5 * re);
1154 r = fabs ((0.5 * im) / s);
1155 }
1156
1157 COMPLEX_ASSIGN (v, r, copysign (s, im));
1158 }
1159 return v;
1160}
1161#endif
1162
1163#if !defined(HAVE_CSQRTL) && defined(HAVE_COPYSIGNL) && defined(HAVE_SQRTL) && defined(HAVE_FABSL) && defined(HAVE_HYPOTL)
2cdc88b6 1164#define HAVE_CSQRTL 1
d08d4988
TB
1165long double complex csqrtl (long double complex z);
1166
1409cd0b
FXC
1167long double complex
1168csqrtl (long double complex z)
1169{
1170 long double re, im;
1171 long double complex v;
1172
1173 re = REALPART (z);
1174 im = IMAGPART (z);
1175 if (im == 0)
1176 {
1177 if (re < 0)
1178 {
1179 COMPLEX_ASSIGN (v, 0, copysignl (sqrtl (-re), im));
1180 }
1181 else
1182 {
1183 COMPLEX_ASSIGN (v, fabsl (sqrtl (re)), copysignl (0, im));
1184 }
1185 }
1186 else if (re == 0)
1187 {
1188 long double r;
1189
1190 r = sqrtl (0.5 * fabsl (im));
1191
1192 COMPLEX_ASSIGN (v, copysignl (r, im), r);
1193 }
1194 else
1195 {
1196 long double d, r, s;
1197
1198 d = hypotl (re, im);
1199 /* Use the identity 2 Re res Im res = Im x
1200 to avoid cancellation error in d +/- Re x. */
1201 if (re > 0)
1202 {
1203 r = sqrtl (0.5 * d + 0.5 * re);
1204 s = (0.5 * im) / r;
1205 }
1206 else
1207 {
1208 s = sqrtl (0.5 * d - 0.5 * re);
1209 r = fabsl ((0.5 * im) / s);
1210 }
1211
1212 COMPLEX_ASSIGN (v, r, copysignl (s, im));
1213 }
1214 return v;
1215}
1216#endif
1217
1218
1219/* sinh(a + i b) = sinh(a) cos(b) + i cosh(a) sin(b) */
1220#if !defined(HAVE_CSINHF)
2cdc88b6 1221#define HAVE_CSINHF 1
d08d4988
TB
1222float complex csinhf (float complex a);
1223
1409cd0b
FXC
1224float complex
1225csinhf (float complex a)
1226{
1227 float r, i;
1228 float complex v;
1229
1230 r = REALPART (a);
1231 i = IMAGPART (a);
1232 COMPLEX_ASSIGN (v, sinhf (r) * cosf (i), coshf (r) * sinf (i));
1233 return v;
1234}
1235#endif
1236
1237#if !defined(HAVE_CSINH)
2cdc88b6 1238#define HAVE_CSINH 1
d08d4988
TB
1239double complex csinh (double complex a);
1240
1409cd0b
FXC
1241double complex
1242csinh (double complex a)
1243{
1244 double r, i;
1245 double complex v;
1246
1247 r = REALPART (a);
1248 i = IMAGPART (a);
1249 COMPLEX_ASSIGN (v, sinh (r) * cos (i), cosh (r) * sin (i));
1250 return v;
1251}
1252#endif
1253
1254#if !defined(HAVE_CSINHL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
2cdc88b6 1255#define HAVE_CSINHL 1
d08d4988
TB
1256long double complex csinhl (long double complex a);
1257
1409cd0b
FXC
1258long double complex
1259csinhl (long double complex a)
1260{
1261 long double r, i;
1262 long double complex v;
1263
1264 r = REALPART (a);
1265 i = IMAGPART (a);
1266 COMPLEX_ASSIGN (v, sinhl (r) * cosl (i), coshl (r) * sinl (i));
1267 return v;
1268}
1269#endif
1270
1271
5bde96d2 1272/* cosh(a + i b) = cosh(a) cos(b) + i sinh(a) sin(b) */
1409cd0b 1273#if !defined(HAVE_CCOSHF)
2cdc88b6 1274#define HAVE_CCOSHF 1
d08d4988
TB
1275float complex ccoshf (float complex a);
1276
1409cd0b
FXC
1277float complex
1278ccoshf (float complex a)
1279{
1280 float r, i;
1281 float complex v;
1282
1283 r = REALPART (a);
1284 i = IMAGPART (a);
5bde96d2 1285 COMPLEX_ASSIGN (v, coshf (r) * cosf (i), sinhf (r) * sinf (i));
1409cd0b
FXC
1286 return v;
1287}
1288#endif
1289
1290#if !defined(HAVE_CCOSH)
2cdc88b6 1291#define HAVE_CCOSH 1
d08d4988
TB
1292double complex ccosh (double complex a);
1293
1409cd0b
FXC
1294double complex
1295ccosh (double complex a)
1296{
1297 double r, i;
1298 double complex v;
1299
1300 r = REALPART (a);
1301 i = IMAGPART (a);
5bde96d2 1302 COMPLEX_ASSIGN (v, cosh (r) * cos (i), sinh (r) * sin (i));
1409cd0b
FXC
1303 return v;
1304}
1305#endif
1306
1307#if !defined(HAVE_CCOSHL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
2cdc88b6 1308#define HAVE_CCOSHL 1
d08d4988
TB
1309long double complex ccoshl (long double complex a);
1310
1409cd0b
FXC
1311long double complex
1312ccoshl (long double complex a)
1313{
1314 long double r, i;
1315 long double complex v;
1316
1317 r = REALPART (a);
1318 i = IMAGPART (a);
5bde96d2 1319 COMPLEX_ASSIGN (v, coshl (r) * cosl (i), sinhl (r) * sinl (i));
1409cd0b
FXC
1320 return v;
1321}
1322#endif
1323
1324
5bde96d2 1325/* tanh(a + i b) = (tanh(a) + i tan(b)) / (1 + i tanh(a) tan(b)) */
1409cd0b 1326#if !defined(HAVE_CTANHF)
2cdc88b6 1327#define HAVE_CTANHF 1
d08d4988
TB
1328float complex ctanhf (float complex a);
1329
1409cd0b
FXC
1330float complex
1331ctanhf (float complex a)
1332{
1333 float rt, it;
1334 float complex n, d;
1335
1336 rt = tanhf (REALPART (a));
1337 it = tanf (IMAGPART (a));
1338 COMPLEX_ASSIGN (n, rt, it);
5bde96d2 1339 COMPLEX_ASSIGN (d, 1, rt * it);
1409cd0b
FXC
1340
1341 return n / d;
1342}
1343#endif
1344
1345#if !defined(HAVE_CTANH)
2cdc88b6 1346#define HAVE_CTANH 1
d08d4988 1347double complex ctanh (double complex a);
1409cd0b
FXC
1348double complex
1349ctanh (double complex a)
1350{
1351 double rt, it;
1352 double complex n, d;
1353
1354 rt = tanh (REALPART (a));
1355 it = tan (IMAGPART (a));
1356 COMPLEX_ASSIGN (n, rt, it);
5bde96d2 1357 COMPLEX_ASSIGN (d, 1, rt * it);
1409cd0b
FXC
1358
1359 return n / d;
1360}
1361#endif
1362
1363#if !defined(HAVE_CTANHL) && defined(HAVE_TANL) && defined(HAVE_TANHL)
2cdc88b6 1364#define HAVE_CTANHL 1
d08d4988
TB
1365long double complex ctanhl (long double complex a);
1366
1409cd0b
FXC
1367long double complex
1368ctanhl (long double complex a)
1369{
1370 long double rt, it;
1371 long double complex n, d;
1372
1373 rt = tanhl (REALPART (a));
1374 it = tanl (IMAGPART (a));
1375 COMPLEX_ASSIGN (n, rt, it);
5bde96d2 1376 COMPLEX_ASSIGN (d, 1, rt * it);
1409cd0b
FXC
1377
1378 return n / d;
1379}
1380#endif
1381
1382
1383/* sin(a + i b) = sin(a) cosh(b) + i cos(a) sinh(b) */
1384#if !defined(HAVE_CSINF)
2cdc88b6 1385#define HAVE_CSINF 1
d08d4988
TB
1386float complex csinf (float complex a);
1387
1409cd0b
FXC
1388float complex
1389csinf (float complex a)
1390{
1391 float r, i;
1392 float complex v;
1393
1394 r = REALPART (a);
1395 i = IMAGPART (a);
1396 COMPLEX_ASSIGN (v, sinf (r) * coshf (i), cosf (r) * sinhf (i));
1397 return v;
1398}
1399#endif
1400
1401#if !defined(HAVE_CSIN)
2cdc88b6 1402#define HAVE_CSIN 1
d08d4988
TB
1403double complex csin (double complex a);
1404
1409cd0b
FXC
1405double complex
1406csin (double complex a)
1407{
1408 double r, i;
1409 double complex v;
1410
1411 r = REALPART (a);
1412 i = IMAGPART (a);
1413 COMPLEX_ASSIGN (v, sin (r) * cosh (i), cos (r) * sinh (i));
1414 return v;
1415}
1416#endif
1417
1418#if !defined(HAVE_CSINL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
2cdc88b6 1419#define HAVE_CSINL 1
d08d4988
TB
1420long double complex csinl (long double complex a);
1421
1409cd0b
FXC
1422long double complex
1423csinl (long double complex a)
1424{
1425 long double r, i;
1426 long double complex v;
1427
1428 r = REALPART (a);
1429 i = IMAGPART (a);
1430 COMPLEX_ASSIGN (v, sinl (r) * coshl (i), cosl (r) * sinhl (i));
1431 return v;
1432}
1433#endif
1434
1435
1436/* cos(a + i b) = cos(a) cosh(b) - i sin(a) sinh(b) */
1437#if !defined(HAVE_CCOSF)
2cdc88b6 1438#define HAVE_CCOSF 1
d08d4988
TB
1439float complex ccosf (float complex a);
1440
1409cd0b
FXC
1441float complex
1442ccosf (float complex a)
1443{
1444 float r, i;
1445 float complex v;
1446
1447 r = REALPART (a);
1448 i = IMAGPART (a);
1449 COMPLEX_ASSIGN (v, cosf (r) * coshf (i), - (sinf (r) * sinhf (i)));
1450 return v;
1451}
1452#endif
1453
1454#if !defined(HAVE_CCOS)
2cdc88b6 1455#define HAVE_CCOS 1
d08d4988
TB
1456double complex ccos (double complex a);
1457
1409cd0b
FXC
1458double complex
1459ccos (double complex a)
1460{
1461 double r, i;
1462 double complex v;
1463
1464 r = REALPART (a);
1465 i = IMAGPART (a);
1466 COMPLEX_ASSIGN (v, cos (r) * cosh (i), - (sin (r) * sinh (i)));
1467 return v;
1468}
1469#endif
1470
1471#if !defined(HAVE_CCOSL) && defined(HAVE_COSL) && defined(HAVE_COSHL) && defined(HAVE_SINL) && defined(HAVE_SINHL)
2cdc88b6 1472#define HAVE_CCOSL 1
d08d4988
TB
1473long double complex ccosl (long double complex a);
1474
1409cd0b
FXC
1475long double complex
1476ccosl (long double complex a)
1477{
1478 long double r, i;
1479 long double complex v;
1480
1481 r = REALPART (a);
1482 i = IMAGPART (a);
1483 COMPLEX_ASSIGN (v, cosl (r) * coshl (i), - (sinl (r) * sinhl (i)));
1484 return v;
1485}
1486#endif
1487
1488
1489/* tan(a + i b) = (tan(a) + i tanh(b)) / (1 - i tan(a) tanh(b)) */
1490#if !defined(HAVE_CTANF)
2cdc88b6 1491#define HAVE_CTANF 1
d08d4988
TB
1492float complex ctanf (float complex a);
1493
1409cd0b
FXC
1494float complex
1495ctanf (float complex a)
1496{
1497 float rt, it;
1498 float complex n, d;
1499
1500 rt = tanf (REALPART (a));
1501 it = tanhf (IMAGPART (a));
1502 COMPLEX_ASSIGN (n, rt, it);
1503 COMPLEX_ASSIGN (d, 1, - (rt * it));
1504
1505 return n / d;
1506}
1507#endif
1508
1509#if !defined(HAVE_CTAN)
2cdc88b6 1510#define HAVE_CTAN 1
d08d4988
TB
1511double complex ctan (double complex a);
1512
1409cd0b
FXC
1513double complex
1514ctan (double complex a)
1515{
1516 double rt, it;
1517 double complex n, d;
1518
1519 rt = tan (REALPART (a));
1520 it = tanh (IMAGPART (a));
1521 COMPLEX_ASSIGN (n, rt, it);
1522 COMPLEX_ASSIGN (d, 1, - (rt * it));
1523
1524 return n / d;
1525}
1526#endif
1527
1528#if !defined(HAVE_CTANL) && defined(HAVE_TANL) && defined(HAVE_TANHL)
2cdc88b6 1529#define HAVE_CTANL 1
d08d4988
TB
1530long double complex ctanl (long double complex a);
1531
1409cd0b
FXC
1532long double complex
1533ctanl (long double complex a)
1534{
1535 long double rt, it;
1536 long double complex n, d;
1537
1538 rt = tanl (REALPART (a));
1539 it = tanhl (IMAGPART (a));
1540 COMPLEX_ASSIGN (n, rt, it);
1541 COMPLEX_ASSIGN (d, 1, - (rt * it));
1542
1543 return n / d;
1544}
1545#endif
1546
fb0a0e15 1547
504ed63a
TB
1548/* Complex ASIN. Returns wrongly NaN for infinite arguments.
1549 Algorithm taken from Abramowitz & Stegun. */
1550
1551#if !defined(HAVE_CASINF) && defined(HAVE_CLOGF) && defined(HAVE_CSQRTF)
1552#define HAVE_CASINF 1
d08d4988
TB
1553complex float casinf (complex float z);
1554
504ed63a
TB
1555complex float
1556casinf (complex float z)
1557{
1558 return -I*clogf (I*z + csqrtf (1.0f-z*z));
1559}
1560#endif
1561
1562
1563#if !defined(HAVE_CASIN) && defined(HAVE_CLOG) && defined(HAVE_CSQRT)
1564#define HAVE_CASIN 1
d08d4988
TB
1565complex double casin (complex double z);
1566
504ed63a
TB
1567complex double
1568casin (complex double z)
1569{
1570 return -I*clog (I*z + csqrt (1.0-z*z));
1571}
1572#endif
1573
1574
1575#if !defined(HAVE_CASINL) && defined(HAVE_CLOGL) && defined(HAVE_CSQRTL)
1576#define HAVE_CASINL 1
d08d4988
TB
1577complex long double casinl (complex long double z);
1578
504ed63a
TB
1579complex long double
1580casinl (complex long double z)
1581{
1582 return -I*clogl (I*z + csqrtl (1.0L-z*z));
1583}
1584#endif
1585
1586
1587/* Complex ACOS. Returns wrongly NaN for infinite arguments.
1588 Algorithm taken from Abramowitz & Stegun. */
1589
1590#if !defined(HAVE_CACOSF) && defined(HAVE_CLOGF) && defined(HAVE_CSQRTF)
1591#define HAVE_CACOSF 1
d08d4988
TB
1592complex float cacosf (complex float z);
1593
504ed63a
TB
1594complex float
1595cacosf (complex float z)
1596{
d08d4988 1597 return -I*clogf (z + I*csqrtf (1.0f-z*z));
504ed63a
TB
1598}
1599#endif
1600
1601
504ed63a
TB
1602#if !defined(HAVE_CACOS) && defined(HAVE_CLOG) && defined(HAVE_CSQRT)
1603#define HAVE_CACOS 1
d08d4988
TB
1604complex double cacos (complex double z);
1605
1606complex double
504ed63a
TB
1607cacos (complex double z)
1608{
1609 return -I*clog (z + I*csqrt (1.0-z*z));
1610}
1611#endif
1612
1613
1614#if !defined(HAVE_CACOSL) && defined(HAVE_CLOGL) && defined(HAVE_CSQRTL)
1615#define HAVE_CACOSL 1
d08d4988
TB
1616complex long double cacosl (complex long double z);
1617
504ed63a
TB
1618complex long double
1619cacosl (complex long double z)
1620{
1621 return -I*clogl (z + I*csqrtl (1.0L-z*z));
1622}
1623#endif
1624
1625
1626/* Complex ATAN. Returns wrongly NaN for infinite arguments.
1627 Algorithm taken from Abramowitz & Stegun. */
1628
1629#if !defined(HAVE_CATANF) && defined(HAVE_CLOGF)
1630#define HAVE_CACOSF 1
d08d4988
TB
1631complex float catanf (complex float z);
1632
504ed63a
TB
1633complex float
1634catanf (complex float z)
1635{
1636 return I*clogf ((I+z)/(I-z))/2.0f;
1637}
1638#endif
1639
1640
1641#if !defined(HAVE_CATAN) && defined(HAVE_CLOG)
1642#define HAVE_CACOS 1
d08d4988
TB
1643complex double catan (complex double z);
1644
504ed63a
TB
1645complex double
1646catan (complex double z)
1647{
1648 return I*clog ((I+z)/(I-z))/2.0;
1649}
1650#endif
1651
1652
1653#if !defined(HAVE_CATANL) && defined(HAVE_CLOGL)
1654#define HAVE_CACOSL 1
d08d4988
TB
1655complex long double catanl (complex long double z);
1656
504ed63a
TB
1657complex long double
1658catanl (complex long double z)
1659{
1660 return I*clogl ((I+z)/(I-z))/2.0L;
1661}
1662#endif
1663
1664
1665/* Complex ASINH. Returns wrongly NaN for infinite arguments.
1666 Algorithm taken from Abramowitz & Stegun. */
1667
1668#if !defined(HAVE_CASINHF) && defined(HAVE_CLOGF) && defined(HAVE_CSQRTF)
1669#define HAVE_CASINHF 1
d08d4988
TB
1670complex float casinhf (complex float z);
1671
504ed63a
TB
1672complex float
1673casinhf (complex float z)
1674{
1675 return clogf (z + csqrtf (z*z+1.0f));
1676}
1677#endif
1678
1679
1680#if !defined(HAVE_CASINH) && defined(HAVE_CLOG) && defined(HAVE_CSQRT)
1681#define HAVE_CASINH 1
d08d4988
TB
1682complex double casinh (complex double z);
1683
504ed63a
TB
1684complex double
1685casinh (complex double z)
1686{
1687 return clog (z + csqrt (z*z+1.0));
1688}
1689#endif
1690
1691
1692#if !defined(HAVE_CASINHL) && defined(HAVE_CLOGL) && defined(HAVE_CSQRTL)
1693#define HAVE_CASINHL 1
d08d4988
TB
1694complex long double casinhl (complex long double z);
1695
504ed63a
TB
1696complex long double
1697casinhl (complex long double z)
1698{
1699 return clogl (z + csqrtl (z*z+1.0L));
1700}
1701#endif
1702
1703
1704/* Complex ACOSH. Returns wrongly NaN for infinite arguments.
1705 Algorithm taken from Abramowitz & Stegun. */
1706
1707#if !defined(HAVE_CACOSHF) && defined(HAVE_CLOGF) && defined(HAVE_CSQRTF)
1708#define HAVE_CACOSHF 1
d08d4988
TB
1709complex float cacoshf (complex float z);
1710
504ed63a
TB
1711complex float
1712cacoshf (complex float z)
1713{
1714 return clogf (z + csqrtf (z-1.0f) * csqrtf (z+1.0f));
1715}
1716#endif
1717
1718
1719#if !defined(HAVE_CACOSH) && defined(HAVE_CLOG) && defined(HAVE_CSQRT)
1720#define HAVE_CACOSH 1
d08d4988
TB
1721complex double cacosh (complex double z);
1722
504ed63a
TB
1723complex double
1724cacosh (complex double z)
1725{
1726 return clog (z + csqrt (z-1.0) * csqrt (z+1.0));
1727}
1728#endif
1729
1730
1731#if !defined(HAVE_CACOSHL) && defined(HAVE_CLOGL) && defined(HAVE_CSQRTL)
1732#define HAVE_CACOSHL 1
d08d4988
TB
1733complex long double cacoshl (complex long double z);
1734
504ed63a
TB
1735complex long double
1736cacoshl (complex long double z)
1737{
1738 return clogl (z + csqrtl (z-1.0L) * csqrtl (z+1.0L));
1739}
1740#endif
1741
1742
1743/* Complex ATANH. Returns wrongly NaN for infinite arguments.
1744 Algorithm taken from Abramowitz & Stegun. */
1745
1746#if !defined(HAVE_CATANHF) && defined(HAVE_CLOGF)
1747#define HAVE_CATANHF 1
d08d4988
TB
1748complex float catanhf (complex float z);
1749
504ed63a
TB
1750complex float
1751catanhf (complex float z)
1752{
1753 return clogf ((1.0f+z)/(1.0f-z))/2.0f;
1754}
1755#endif
1756
1757
1758#if !defined(HAVE_CATANH) && defined(HAVE_CLOG)
1759#define HAVE_CATANH 1
d08d4988
TB
1760complex double catanh (complex double z);
1761
504ed63a
TB
1762complex double
1763catanh (complex double z)
1764{
1765 return clog ((1.0+z)/(1.0-z))/2.0;
1766}
1767#endif
1768
1769#if !defined(HAVE_CATANHL) && defined(HAVE_CLOGL)
1770#define HAVE_CATANHL 1
d08d4988
TB
1771complex long double catanhl (complex long double z);
1772
504ed63a
TB
1773complex long double
1774catanhl (complex long double z)
1775{
1776 return clogl ((1.0L+z)/(1.0L-z))/2.0L;
1777}
1778#endif
1779
1780
fb0a0e15
FXC
1781#if !defined(HAVE_TGAMMA)
1782#define HAVE_TGAMMA 1
d08d4988 1783double tgamma (double);
fb0a0e15
FXC
1784
1785/* Fallback tgamma() function. Uses the algorithm from
1786 http://www.netlib.org/specfun/gamma and references therein. */
1787
1788#undef SQRTPI
1789#define SQRTPI 0.9189385332046727417803297
1790
1791#undef PI
1792#define PI 3.1415926535897932384626434
1793
1794double
1795tgamma (double x)
1796{
1797 int i, n, parity;
1798 double fact, res, sum, xden, xnum, y, y1, ysq, z;
1799
1800 static double p[8] = {
1801 -1.71618513886549492533811e0, 2.47656508055759199108314e1,
1802 -3.79804256470945635097577e2, 6.29331155312818442661052e2,
1803 8.66966202790413211295064e2, -3.14512729688483675254357e4,
1804 -3.61444134186911729807069e4, 6.64561438202405440627855e4 };
1805
1806 static double q[8] = {
1807 -3.08402300119738975254353e1, 3.15350626979604161529144e2,
1808 -1.01515636749021914166146e3, -3.10777167157231109440444e3,
1809 2.25381184209801510330112e4, 4.75584627752788110767815e3,
1810 -1.34659959864969306392456e5, -1.15132259675553483497211e5 };
1811
1812 static double c[7] = { -1.910444077728e-03,
1813 8.4171387781295e-04, -5.952379913043012e-04,
1814 7.93650793500350248e-04, -2.777777777777681622553e-03,
1815 8.333333333333333331554247e-02, 5.7083835261e-03 };
1816
1817 static const double xminin = 2.23e-308;
1818 static const double xbig = 171.624;
1819 static const double xnan = __builtin_nan ("0x0"), xinf = __builtin_inf ();
1820 static double eps = 0;
1821
1822 if (eps == 0)
d08d4988 1823 eps = nextafter (1., 2.) - 1.;
fb0a0e15
FXC
1824
1825 parity = 0;
1826 fact = 1;
1827 n = 0;
1828 y = x;
1829
b1012ca4 1830 if (isnan (x))
fb0a0e15
FXC
1831 return x;
1832
1833 if (y <= 0)
1834 {
1835 y = -x;
d08d4988 1836 y1 = trunc (y);
fb0a0e15
FXC
1837 res = y - y1;
1838
1839 if (res != 0)
1840 {
d08d4988 1841 if (y1 != trunc (y1*0.5l)*2)
fb0a0e15 1842 parity = 1;
d08d4988 1843 fact = -PI / sin (PI*res);
fb0a0e15
FXC
1844 y = y + 1;
1845 }
1846 else
1847 return x == 0 ? copysign (xinf, x) : xnan;
1848 }
1849
1850 if (y < eps)
1851 {
1852 if (y >= xminin)
1853 res = 1 / y;
1854 else
1855 return xinf;
1856 }
1857 else if (y < 13)
1858 {
1859 y1 = y;
1860 if (y < 1)
1861 {
1862 z = y;
1863 y = y + 1;
1864 }
1865 else
1866 {
1867 n = (int)y - 1;
1868 y = y - n;
1869 z = y - 1;
1870 }
1871
1872 xnum = 0;
1873 xden = 1;
1874 for (i = 0; i < 8; i++)
1875 {
1876 xnum = (xnum + p[i]) * z;
1877 xden = xden * z + q[i];
1878 }
1879
1880 res = xnum / xden + 1;
1881
1882 if (y1 < y)
1883 res = res / y1;
1884 else if (y1 > y)
1885 for (i = 1; i <= n; i++)
1886 {
1887 res = res * y;
1888 y = y + 1;
1889 }
1890 }
1891 else
1892 {
1893 if (y < xbig)
1894 {
1895 ysq = y * y;
1896 sum = c[6];
1897 for (i = 0; i < 6; i++)
1898 sum = sum / ysq + c[i];
1899
1900 sum = sum/y - y + SQRTPI;
d08d4988
TB
1901 sum = sum + (y - 0.5) * log (y);
1902 res = exp (sum);
fb0a0e15
FXC
1903 }
1904 else
1905 return x < 0 ? xnan : xinf;
1906 }
1907
1908 if (parity)
1909 res = -res;
1910 if (fact != 1)
1911 res = fact / res;
1912
1913 return res;
1914}
1915#endif
1916
1917
1918
1919#if !defined(HAVE_LGAMMA)
1920#define HAVE_LGAMMA 1
d08d4988 1921double lgamma (double);
fb0a0e15
FXC
1922
1923/* Fallback lgamma() function. Uses the algorithm from
1924 http://www.netlib.org/specfun/algama and references therein,
1925 except for negative arguments (where netlib would return +Inf)
1926 where we use the following identity:
1927 lgamma(y) = log(pi/(|y*sin(pi*y)|)) - lgamma(-y)
1928 */
1929
1930double
1931lgamma (double y)
1932{
1933
1934#undef SQRTPI
1935#define SQRTPI 0.9189385332046727417803297
1936
1937#undef PI
1938#define PI 3.1415926535897932384626434
1939
1940#define PNT68 0.6796875
1941#define D1 -0.5772156649015328605195174
1942#define D2 0.4227843350984671393993777
1943#define D4 1.791759469228055000094023
1944
1945 static double p1[8] = {
1946 4.945235359296727046734888e0, 2.018112620856775083915565e2,
1947 2.290838373831346393026739e3, 1.131967205903380828685045e4,
1948 2.855724635671635335736389e4, 3.848496228443793359990269e4,
1949 2.637748787624195437963534e4, 7.225813979700288197698961e3 };
1950 static double q1[8] = {
1951 6.748212550303777196073036e1, 1.113332393857199323513008e3,
1952 7.738757056935398733233834e3, 2.763987074403340708898585e4,
1953 5.499310206226157329794414e4, 6.161122180066002127833352e4,
1954 3.635127591501940507276287e4, 8.785536302431013170870835e3 };
1955 static double p2[8] = {
1956 4.974607845568932035012064e0, 5.424138599891070494101986e2,
1957 1.550693864978364947665077e4, 1.847932904445632425417223e5,
1958 1.088204769468828767498470e6, 3.338152967987029735917223e6,
1959 5.106661678927352456275255e6, 3.074109054850539556250927e6 };
1960 static double q2[8] = {
1961 1.830328399370592604055942e2, 7.765049321445005871323047e3,
1962 1.331903827966074194402448e5, 1.136705821321969608938755e6,
1963 5.267964117437946917577538e6, 1.346701454311101692290052e7,
1964 1.782736530353274213975932e7, 9.533095591844353613395747e6 };
1965 static double p4[8] = {
1966 1.474502166059939948905062e4, 2.426813369486704502836312e6,
1967 1.214755574045093227939592e8, 2.663432449630976949898078e9,
1968 2.940378956634553899906876e10, 1.702665737765398868392998e11,
1969 4.926125793377430887588120e11, 5.606251856223951465078242e11 };
1970 static double q4[8] = {
1971 2.690530175870899333379843e3, 6.393885654300092398984238e5,
1972 4.135599930241388052042842e7, 1.120872109616147941376570e9,
1973 1.488613728678813811542398e10, 1.016803586272438228077304e11,
1974 3.417476345507377132798597e11, 4.463158187419713286462081e11 };
1975 static double c[7] = {
1976 -1.910444077728e-03, 8.4171387781295e-04,
1977 -5.952379913043012e-04, 7.93650793500350248e-04,
1978 -2.777777777777681622553e-03, 8.333333333333333331554247e-02,
1979 5.7083835261e-03 };
1980
1981 static double xbig = 2.55e305, xinf = __builtin_inf (), eps = 0,
1982 frtbig = 2.25e76;
1983
1984 int i;
1985 double corr, res, xden, xm1, xm2, xm4, xnum, ysq;
1986
1987 if (eps == 0)
d08d4988 1988 eps = __builtin_nextafter (1., 2.) - 1.;
fb0a0e15
FXC
1989
1990 if ((y > 0) && (y <= xbig))
1991 {
1992 if (y <= eps)
d08d4988 1993 res = -log (y);
fb0a0e15
FXC
1994 else if (y <= 1.5)
1995 {
1996 if (y < PNT68)
1997 {
d08d4988 1998 corr = -log (y);
fb0a0e15
FXC
1999 xm1 = y;
2000 }
2001 else
2002 {
2003 corr = 0;
2004 xm1 = (y - 0.5) - 0.5;
2005 }
2006
2007 if ((y <= 0.5) || (y >= PNT68))
2008 {
2009 xden = 1;
2010 xnum = 0;
2011 for (i = 0; i < 8; i++)
2012 {
2013 xnum = xnum*xm1 + p1[i];
2014 xden = xden*xm1 + q1[i];
2015 }
2016 res = corr + (xm1 * (D1 + xm1*(xnum/xden)));
2017 }
2018 else
2019 {
2020 xm2 = (y - 0.5) - 0.5;
2021 xden = 1;
2022 xnum = 0;
2023 for (i = 0; i < 8; i++)
2024 {
2025 xnum = xnum*xm2 + p2[i];
2026 xden = xden*xm2 + q2[i];
2027 }
2028 res = corr + xm2 * (D2 + xm2*(xnum/xden));
2029 }
2030 }
2031 else if (y <= 4)
2032 {
2033 xm2 = y - 2;
2034 xden = 1;
2035 xnum = 0;
2036 for (i = 0; i < 8; i++)
2037 {
2038 xnum = xnum*xm2 + p2[i];
2039 xden = xden*xm2 + q2[i];
2040 }
2041 res = xm2 * (D2 + xm2*(xnum/xden));
2042 }
2043 else if (y <= 12)
2044 {
2045 xm4 = y - 4;
2046 xden = -1;
2047 xnum = 0;
2048 for (i = 0; i < 8; i++)
2049 {
2050 xnum = xnum*xm4 + p4[i];
2051 xden = xden*xm4 + q4[i];
2052 }
2053 res = D4 + xm4*(xnum/xden);
2054 }
2055 else
2056 {
2057 res = 0;
2058 if (y <= frtbig)
2059 {
2060 res = c[6];
2061 ysq = y * y;
2062 for (i = 0; i < 6; i++)
2063 res = res / ysq + c[i];
2064 }
2065 res = res/y;
d08d4988 2066 corr = log (y);
fb0a0e15
FXC
2067 res = res + SQRTPI - 0.5*corr;
2068 res = res + y*(corr-1);
2069 }
2070 }
2071 else if (y < 0 && __builtin_floor (y) != y)
2072 {
2073 /* lgamma(y) = log(pi/(|y*sin(pi*y)|)) - lgamma(-y)
2074 For abs(y) very close to zero, we use a series expansion to
2075 the first order in y to avoid overflow. */
2076 if (y > -1.e-100)
2077 res = -2 * log (fabs (y)) - lgamma (-y);
2078 else
2079 res = log (PI / fabs (y * sin (PI * y))) - lgamma (-y);
2080 }
2081 else
2082 res = xinf;
2083
2084 return res;
2085}
2086#endif
2087
2088
2089#if defined(HAVE_TGAMMA) && !defined(HAVE_TGAMMAF)
2090#define HAVE_TGAMMAF 1
d08d4988 2091float tgammaf (float);
fb0a0e15
FXC
2092
2093float
2094tgammaf (float x)
2095{
2096 return (float) tgamma ((double) x);
2097}
2098#endif
2099
2100#if defined(HAVE_LGAMMA) && !defined(HAVE_LGAMMAF)
2101#define HAVE_LGAMMAF 1
d08d4988 2102float lgammaf (float);
fb0a0e15
FXC
2103
2104float
2105lgammaf (float x)
2106{
2107 return (float) lgamma ((double) x);
2108}
2109#endif