1 /* Return value of complex exponential function for float complex 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 <fenv.h>
23 #include <math.h>
24 
25 #include "math_private.h"
26 
27 
28 __complex__ float
__cexpf(__complex__ float x)29 __cexpf (__complex__ float x)
30 {
31   __complex__ float retval;
32   int rcls = fpclassify (__real__ x);
33   int icls = fpclassify (__imag__ x);
34 
35   if (rcls >= FP_ZERO)
36     {
37       /* Real part is finite.  */
38       if (icls >= FP_ZERO)
39 	{
40 	  /* Imaginary part is finite.  */
41 	  float exp_val = __ieee754_expf (__real__ x);
42 	  float sinix, cosix;
43 
44 	  __sincosf (__imag__ x, &sinix, &cosix);
45 
46 	  if (isfinite (exp_val))
47 	    {
48 	      __real__ retval = exp_val * cosix;
49 	      __imag__ retval = exp_val * sinix;
50 	    }
51 	  else
52 	    {
53 	      __real__ retval = __copysignf (exp_val, cosix);
54 	      __imag__ retval = __copysignf (exp_val, sinix);
55 	    }
56 	}
57       else
58 	{
59 	  /* If the imaginary part is +-inf or NaN and the real part
60 	     is not +-inf the result is NaN + iNaN.  */
61 	  __real__ retval = __nanf ("");
62 	  __imag__ retval = __nanf ("");
63 
64 #ifdef FE_INVALID
65 	  feraiseexcept (FE_INVALID);
66 #endif
67 	}
68     }
69   else if (rcls == FP_INFINITE)
70     {
71       /* Real part is infinite.  */
72       if (icls >= FP_ZERO)
73 	{
74 	  /* Imaginary part is finite.  */
75 	  float value = signbit (__real__ x) ? 0.0 : HUGE_VALF;
76 
77 	  if (icls == FP_ZERO)
78 	    {
79 	      /* Imaginary part is 0.0.  */
80 	      __real__ retval = value;
81 	      __imag__ retval = __imag__ x;
82 	    }
83 	  else
84 	    {
85 	      float sinix, cosix;
86 
87 	      __sincosf (__imag__ x, &sinix, &cosix);
88 
89 	      __real__ retval = __copysignf (value, cosix);
90 	      __imag__ retval = __copysignf (value, sinix);
91 	    }
92 	}
93       else if (signbit (__real__ x) == 0)
94 	{
95 	  __real__ retval = HUGE_VALF;
96 	  __imag__ retval = __nanf ("");
97 
98 #ifdef FE_INVALID
99 	  if (icls == FP_INFINITE)
100 	    feraiseexcept (FE_INVALID);
101 #endif
102 	}
103       else
104 	{
105 	  __real__ retval = 0.0;
106 	  __imag__ retval = __copysignf (0.0, __imag__ x);
107 	}
108     }
109   else
110     {
111       /* If the real part is NaN the result is NaN + iNaN.  */
112       __real__ retval = __nanf ("");
113       __imag__ retval = __nanf ("");
114 
115 #ifdef FE_INVALID
116       if (rcls != FP_NAN || icls != FP_NAN)
117 	feraiseexcept (FE_INVALID);
118 #endif
119     }
120 
121   return retval;
122 }
123 weak_alias (__cexpf, cexpf)
124