(root)/
gcc-13.2.0/
libquadmath/
math/
atanhq.c
       1  /* s_atanhl.c -- long double version of s_atan.c.
       2   * Conversion to long double by Ulrich Drepper,
       3   * Cygnus Support, drepper@cygnus.com.
       4   */
       5  
       6  /*
       7   * ====================================================
       8   * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
       9   *
      10   * Developed at SunPro, a Sun Microsystems, Inc. business.
      11   * Permission to use, copy, modify, and distribute this
      12   * software is freely granted, provided that this notice
      13   * is preserved.
      14   * ====================================================
      15   */
      16  
      17  /* atanhq(x)
      18   * Method :
      19   *    1.Reduced x to positive by atanh(-x) = -atanh(x)
      20   *    2.For x>=0.5
      21   *                   1              2x                          x
      22   *	atanhl(x) = --- * log(1 + -------) = 0.5 * log1p(2 * --------)
      23   *                   2             1 - x                      1 - x
      24   *
      25   *	For x<0.5
      26   *	atanhl(x) = 0.5*log1pq(2x+2x*x/(1-x))
      27   *
      28   * Special cases:
      29   *	atanhl(x) is NaN if |x| > 1 with signal;
      30   *	atanhl(NaN) is that NaN with no signal;
      31   *	atanhl(+-1) is +-INF with signal.
      32   *
      33   */
      34  
      35  #include "quadmath-imp.h"
      36  
      37  static const __float128 one = 1, huge = 1e4900Q;
      38  
      39  static const __float128 zero = 0;
      40  
      41  __float128
      42  atanhq(__float128 x)
      43  {
      44  	__float128 t;
      45  	uint32_t jx, ix;
      46  	ieee854_float128 u;
      47  
      48  	u.value = x;
      49  	jx = u.words32.w0;
      50  	ix = jx & 0x7fffffff;
      51  	u.words32.w0 = ix;
      52  	if (ix >= 0x3fff0000) /* |x| >= 1.0 or infinity or NaN */
      53  	  {
      54  	    if (u.value == one)
      55  	      return x/zero;
      56  	    else
      57  	      return (x-x)/(x-x);
      58  	  }
      59  	if(ix<0x3fc60000 && (huge+x)>zero)	/* x < 2^-57 */
      60  	  {
      61  	    math_check_force_underflow (x);
      62  	    return x;
      63  	  }
      64  
      65  	if(ix<0x3ffe0000) {		/* x < 0.5 */
      66  	    t = u.value+u.value;
      67  	    t = 0.5*log1pq(t+t*u.value/(one-u.value));
      68  	} else
      69  	    t = 0.5*log1pq((u.value+u.value)/(one-u.value));
      70  	if(jx & 0x80000000) return -t; else return t;
      71  }