Blame sysdeps/ieee754/ldbl-128/e_coshl.c

Packit 6c4009
/*
Packit 6c4009
 * ====================================================
Packit 6c4009
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Packit 6c4009
 *
Packit 6c4009
 * Developed at SunPro, a Sun Microsystems, Inc. business.
Packit 6c4009
 * Permission to use, copy, modify, and distribute this
Packit 6c4009
 * software is freely granted, provided that this notice
Packit 6c4009
 * is preserved.
Packit 6c4009
 * ====================================================
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
/* Changes for 128-bit long double are
Packit 6c4009
   Copyright (C) 2001 Stephen L. Moshier <moshier@na-net.ornl.gov>
Packit 6c4009
   and are incorporated herein by permission of the author.  The author
Packit 6c4009
   reserves the right to distribute this material elsewhere under different
Packit 6c4009
   copying permissions.  These modifications are distributed here under
Packit 6c4009
   the following terms:
Packit 6c4009
Packit 6c4009
    This library is free software; you can redistribute it and/or
Packit 6c4009
    modify it under the terms of the GNU Lesser General Public
Packit 6c4009
    License as published by the Free Software Foundation; either
Packit 6c4009
    version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
    This library is distributed in the hope that it will be useful,
Packit 6c4009
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
    Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
    You should have received a copy of the GNU Lesser General Public
Packit 6c4009
    License along with this library; if not, see
Packit 6c4009
    <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
/* __ieee754_coshl(x)
Packit 6c4009
 * Method :
Packit 6c4009
 * mathematically coshl(x) if defined to be (exp(x)+exp(-x))/2
Packit 6c4009
 *      1. Replace x by |x| (coshl(x) = coshl(-x)).
Packit 6c4009
 *      2.
Packit 6c4009
 *                                                      [ exp(x) - 1 ]^2
Packit 6c4009
 *          0        <= x <= ln2/2  :  coshl(x) := 1 + -------------------
Packit 6c4009
 *                                                         2*exp(x)
Packit 6c4009
 *
Packit 6c4009
 *                                                 exp(x) +  1/exp(x)
Packit 6c4009
 *          ln2/2    <= x <= 22     :  coshl(x) := -------------------
Packit 6c4009
 *                                                         2
Packit 6c4009
 *          22       <= x <= lnovft :  coshl(x) := expl(x)/2
Packit 6c4009
 *          lnovft   <= x <= ln2ovft:  coshl(x) := expl(x/2)/2 * expl(x/2)
Packit 6c4009
 *          ln2ovft  <  x           :  coshl(x) := huge*huge (overflow)
Packit 6c4009
 *
Packit 6c4009
 * Special cases:
Packit 6c4009
 *      coshl(x) is |x| if x is +INF, -INF, or NaN.
Packit 6c4009
 *      only coshl(0)=1 is exact for finite x.
Packit 6c4009
 */
Packit 6c4009
Packit 6c4009
#include <math.h>
Packit 6c4009
#include <math_private.h>
Packit 6c4009
Packit 6c4009
static const _Float128 one = 1.0, half = 0.5, huge = L(1.0e4900),
Packit 6c4009
ovf_thresh = L(1.1357216553474703894801348310092223067821E4);
Packit 6c4009
Packit 6c4009
_Float128
Packit 6c4009
__ieee754_coshl (_Float128 x)
Packit 6c4009
{
Packit 6c4009
  _Float128 t, w;
Packit 6c4009
  int32_t ex;
Packit 6c4009
  ieee854_long_double_shape_type u;
Packit 6c4009
Packit 6c4009
  u.value = x;
Packit 6c4009
  ex = u.parts32.w0 & 0x7fffffff;
Packit 6c4009
Packit 6c4009
  /* Absolute value of x.  */
Packit 6c4009
  u.parts32.w0 = ex;
Packit 6c4009
Packit 6c4009
  /* x is INF or NaN */
Packit 6c4009
  if (ex >= 0x7fff0000)
Packit 6c4009
    return x * x;
Packit 6c4009
Packit 6c4009
  /* |x| in [0,0.5*ln2], return 1+expm1l(|x|)^2/(2*expl(|x|)) */
Packit 6c4009
  if (ex < 0x3ffd62e4) /* 0.3465728759765625 */
Packit 6c4009
    {
Packit 6c4009
      if (ex < 0x3fb80000) /* |x| < 2^-116 */
Packit 6c4009
	return one;		/* cosh(tiny) = 1 */
Packit 6c4009
      t = __expm1l (u.value);
Packit 6c4009
      w = one + t;
Packit 6c4009
Packit 6c4009
      return one + (t * t) / (w + w);
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* |x| in [0.5*ln2,40], return (exp(|x|)+1/exp(|x|)/2; */
Packit 6c4009
  if (ex < 0x40044000)
Packit 6c4009
    {
Packit 6c4009
      t = __ieee754_expl (u.value);
Packit 6c4009
      return half * t + half / t;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* |x| in [22, ln(maxdouble)] return half*exp(|x|) */
Packit 6c4009
  if (ex <= 0x400c62e3) /* 11356.375 */
Packit 6c4009
    return half * __ieee754_expl (u.value);
Packit 6c4009
Packit 6c4009
  /* |x| in [log(maxdouble), overflowthresold] */
Packit 6c4009
  if (u.value <= ovf_thresh)
Packit 6c4009
    {
Packit 6c4009
      w = __ieee754_expl (half * u.value);
Packit 6c4009
      t = half * w;
Packit 6c4009
      return t * w;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* |x| > overflowthresold, cosh(x) overflow */
Packit 6c4009
  return huge * huge;
Packit 6c4009
}
Packit 6c4009
strong_alias (__ieee754_coshl, __coshl_finite)