Update to LGPL v2.1.
[kopensolaris-gnu/glibc.git] / sysdeps / generic / s_cacoshf.c
1 /* Return arc hyperbole cosine for float value.
2    Copyright (C) 1997 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 #include <complex.h>
22 #include <math.h>
23
24 #include "math_private.h"
25
26 __complex__ float
27 __cacoshf (__complex__ float x)
28 {
29   __complex__ float res;
30   int rcls = fpclassify (__real__ x);
31   int icls = fpclassify (__imag__ x);
32
33   if (rcls <= FP_INFINITE || icls <= FP_INFINITE)
34     {
35       if (icls == FP_INFINITE)
36         {
37           __real__ res = HUGE_VALF;
38
39           if (rcls == FP_NAN)
40             __imag__ res = __nanf ("");
41           else
42             __imag__ res = __copysignf ((rcls == FP_INFINITE
43                                          ? (__real__ x < 0.0
44                                             ? M_PI - M_PI_4 : M_PI_4)
45                                          : M_PI_2), __imag__ x);
46         }
47       else if (rcls == FP_INFINITE)
48         {
49           __real__ res = HUGE_VALF;
50
51           if (icls >= FP_ZERO)
52             __imag__ res = __copysignf (signbit (__real__ x) ? M_PI : 0.0,
53                                         __imag__ x);
54           else
55             __imag__ res = __nanf ("");
56         }
57       else
58         {
59           __real__ res = __nanf ("");
60           __imag__ res = __nanf ("");
61         }
62     }
63   else if (rcls == FP_ZERO && icls == FP_ZERO)
64     {
65       __real__ res = 0.0;
66       __imag__ res = __copysignf (M_PI_2, __imag__ x);
67     }
68   else
69     {
70 #if 1
71       __complex__ float y;
72
73       __real__ y = (__real__ x - __imag__ x) * (__real__ x + __imag__ x) - 1.0;
74       __imag__ y = 2.0 * __real__ x * __imag__ x;
75
76       y = __csqrtf (y);
77
78       __real__ y += __real__ x;
79       __imag__ y += __imag__ x;
80
81       res = __clogf (y);
82 #else
83       float re2 = __real__ x * __real__ x;
84       float im2 = __imag__ x * __imag__ x;
85       float sq = re2 - im2 - 1.0;
86       float ro = __ieee754_sqrtf (sq * sq + 4 * re2 * im2);
87       float a = __ieee754_sqrtf ((sq + ro) / 2.0);
88       float b = __ieee754_sqrtf ((-sq + ro) / 2.0);
89
90       __real__ res = 0.5 * __ieee754_logf (re2 + __real__ x * 2 * a
91                                            + im2 + __imag__ x * 2 * b
92                                            + ro);
93       __imag__ res = __ieee754_atan2f (__imag__ x + b, __real__ x + a);
94 #endif
95     }
96
97   return res;
98 }
99 weak_alias (__cacoshf, cacoshf)