Back to index

glibc  2.9
s_cexp.c
Go to the documentation of this file.
00001 /* Return value of complex exponential function for double complex value.
00002    Copyright (C) 1997 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include <complex.h>
00022 #include <fenv.h>
00023 #include <math.h>
00024 
00025 #include "math_private.h"
00026 
00027 
00028 __complex__ double
00029 __cexp (__complex__ double x)
00030 {
00031   __complex__ double retval;
00032   int rcls = fpclassify (__real__ x);
00033   int icls = fpclassify (__imag__ x);
00034 
00035   if (rcls >= FP_ZERO)
00036     {
00037       /* Real part is finite.  */
00038       if (icls >= FP_ZERO)
00039        {
00040          /* Imaginary part is finite.  */
00041          double exp_val = __ieee754_exp (__real__ x);
00042          double sinix, cosix;
00043 
00044          __sincos (__imag__ x, &sinix, &cosix);
00045 
00046          if (isfinite (exp_val))
00047            {
00048              __real__ retval = exp_val * cosix;
00049              __imag__ retval = exp_val * sinix;
00050            }
00051          else
00052            {
00053              __real__ retval = __copysign (exp_val, cosix);
00054              __imag__ retval = __copysign (exp_val, sinix);
00055            }
00056        }
00057       else
00058        {
00059          /* If the imaginary part is +-inf or NaN and the real part
00060             is not +-inf the result is NaN + iNaN.  */
00061          __real__ retval = __nan ("");
00062          __imag__ retval = __nan ("");
00063 
00064 #ifdef FE_INVALID
00065          feraiseexcept (FE_INVALID);
00066 #endif
00067        }
00068     }
00069   else if (rcls == FP_INFINITE)
00070     {
00071       /* Real part is infinite.  */
00072       if (icls >= FP_ZERO)
00073        {
00074          /* Imaginary part is finite.  */
00075          double value = signbit (__real__ x) ? 0.0 : HUGE_VAL;
00076 
00077          if (icls == FP_ZERO)
00078            {
00079              /* Imaginary part is 0.0.  */
00080              __real__ retval = value;
00081              __imag__ retval = __imag__ x;
00082            }
00083          else
00084            {
00085              double sinix, cosix;
00086 
00087              __sincos (__imag__ x, &sinix, &cosix);
00088 
00089              __real__ retval = __copysign (value, cosix);
00090              __imag__ retval = __copysign (value, sinix);
00091            }
00092        }
00093       else if (signbit (__real__ x) == 0)
00094        {
00095          __real__ retval = HUGE_VAL;
00096          __imag__ retval = __nan ("");
00097 
00098 #ifdef FE_INVALID
00099          if (icls == FP_INFINITE)
00100            feraiseexcept (FE_INVALID);
00101 #endif
00102        }
00103       else
00104        {
00105          __real__ retval = 0.0;
00106          __imag__ retval = __copysign (0.0, __imag__ x);
00107        }
00108     }
00109   else
00110     {
00111       /* If the real part is NaN the result is NaN + iNaN.  */
00112       __real__ retval = __nan ("");
00113       __imag__ retval = __nan ("");
00114 
00115 #ifdef FE_INVALID
00116       if (rcls != FP_NAN || icls != FP_NAN)
00117        feraiseexcept (FE_INVALID);
00118 #endif
00119     }
00120 
00121   return retval;
00122 }
00123 weak_alias (__cexp, cexp)
00124 #ifdef NO_LONG_DOUBLE
00125 strong_alias (__cexp, __cexpl)
00126 weak_alias (__cexp, cexpl)
00127 #endif