Back to index

glibc  2.9
Functions
divtc3.c File Reference
#include <stdbool.h>
#include <math.h>
#include <complex.h>

Go to the source code of this file.

Functions

attribute_hidden long double
_Complex 
__divtc3 (long double a, long double b, long double c, long double d)

Function Documentation

attribute_hidden long double _Complex __divtc3 ( long double  a,
long double  b,
long double  c,
long double  d 
)

Definition at line 26 of file divtc3.c.

{
  long double denom, ratio, x, y;

  /* ??? We can get better behavior from logarithmic scaling instead of
     the division.  But that would mean starting to link libgcc against
     libm.  We could implement something akin to ldexp/frexp as gcc builtins
     fairly easily...  */
  if (fabsl (c) < fabsl (d))
    {
      ratio = c / d;
      denom = (c * ratio) + d;
      x = ((a * ratio) + b) / denom;
      y = ((b * ratio) - a) / denom;
    }
  else
    {
      ratio = d / c;
      denom = (d * ratio) + c;
      x = ((b * ratio) + a) / denom;
      y = (b - (a * ratio)) / denom;
    }

  /* Recover infinities and zeros that computed as NaN+iNaN; the only cases
     are nonzero/zero, infinite/finite, and finite/infinite.  */
  if (isnan (x) && isnan (y))
    {
      if (denom == 0.0 && (!isnan (a) || !isnan (b)))
       {
         x = __copysignl (INFINITY, c) * a;
         y = __copysignl (INFINITY, c) * b;
       }
      else if ((isinf (a) || isinf (b)) && isfinite (c) && isfinite (d))
       {
         a = __copysignl (isinf (a) ? 1 : 0, a);
         b = __copysignl (isinf (b) ? 1 : 0, b);
         x = INFINITY * (a * c + b * d);
         y = INFINITY * (b * c - a * d);
       }
      else if ((isinf (c) || isinf (d)) && isfinite (a) && isfinite (b))
       {
         c = __copysignl (isinf (c) ? 1 : 0, c);
         d = __copysignl (isinf (d) ? 1 : 0, d);
         x = 0.0 * (a * c + b * d);
         y = 0.0 * (b * c - a * d);
       }
    }

  return x + I * y;
}

Here is the call graph for this function: