Blame sysdeps/ieee754/dbl-64/mpatan.c

Packit 6c4009
/*
Packit 6c4009
 * IBM Accurate Mathematical Library
Packit 6c4009
 * written by International Business Machines Corp.
Packit 6c4009
 * Copyright (C) 2001-2018 Free Software Foundation, Inc.
Packit 6c4009
 *
Packit 6c4009
 * This program is free software; you can redistribute it and/or modify
Packit 6c4009
 * it under the terms of the GNU Lesser General Public License as published by
Packit 6c4009
 * the Free Software Foundation; either version 2.1 of the License, or
Packit 6c4009
 * (at your option) any later version.
Packit 6c4009
 *
Packit 6c4009
 * This program 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
Packit 6c4009
 * GNU Lesser General Public License for more details.
Packit 6c4009
 *
Packit 6c4009
 * You should have received a copy of the GNU  Lesser General Public License
Packit 6c4009
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit 6c4009
 */
Packit 6c4009
/******************************************************************/
Packit 6c4009
/*                                                                */
Packit 6c4009
/* MODULE_NAME:mpatan.c                                           */
Packit 6c4009
/*                                                                */
Packit 6c4009
/* FUNCTIONS:mpatan                                               */
Packit 6c4009
/*                                                                */
Packit 6c4009
/* FILES NEEDED: mpa.h endian.h mpatan.h                          */
Packit 6c4009
/*               mpa.c                                            */
Packit 6c4009
/*                                                                */
Packit 6c4009
/* Multi-Precision Atan function subroutine, for precision p >= 4.*/
Packit 6c4009
/* The relative error of the result is bounded by 34.32*r**(1-p), */
Packit 6c4009
/* where r=2**24.                                                 */
Packit 6c4009
/******************************************************************/
Packit 6c4009
Packit 6c4009
#include "endian.h"
Packit 6c4009
#include "mpa.h"
Packit 6c4009
#include <math.h>
Packit 6c4009
Packit 6c4009
#ifndef SECTION
Packit 6c4009
# define SECTION
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#include "mpatan.h"
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
SECTION
Packit 6c4009
__mpatan (mp_no *x, mp_no *y, int p)
Packit 6c4009
{
Packit 6c4009
  int i, m, n;
Packit 6c4009
  double dx;
Packit 6c4009
  mp_no mptwoim1 =
Packit 6c4009
  {
Packit 6c4009
    0,
Packit 6c4009
    {
Packit 6c4009
      0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
Packit 6c4009
      0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
Packit 6c4009
      0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
Packit 6c4009
    }
Packit 6c4009
  };
Packit 6c4009
Packit 6c4009
  mp_no mps, mpsm, mpt, mpt1, mpt2, mpt3;
Packit 6c4009
Packit 6c4009
  /* Choose m and initiate mptwoim1.  */
Packit 6c4009
  if (EX > 0)
Packit 6c4009
    m = 7;
Packit 6c4009
  else if (EX < 0)
Packit 6c4009
    m = 0;
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      __mp_dbl (x, &dx, p);
Packit 6c4009
      dx = fabs (dx);
Packit 6c4009
      for (m = 6; m > 0; m--)
Packit 6c4009
	{
Packit 6c4009
	  if (dx > __atan_xm[m].d)
Packit 6c4009
	    break;
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
  mptwoim1.e = 1;
Packit 6c4009
  mptwoim1.d[0] = 1;
Packit 6c4009
Packit 6c4009
  /* Reduce x m times.  */
Packit 6c4009
  __sqr (x, &mpsm, p);
Packit 6c4009
  if (m == 0)
Packit 6c4009
    __cpy (x, &mps, p);
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      for (i = 0; i < m; i++)
Packit 6c4009
	{
Packit 6c4009
	  __add (&__mpone, &mpsm, &mpt1, p);
Packit 6c4009
	  __mpsqrt (&mpt1, &mpt2, p);
Packit 6c4009
	  __add (&mpt2, &mpt2, &mpt1, p);
Packit 6c4009
	  __add (&__mptwo, &mpsm, &mpt2, p);
Packit 6c4009
	  __add (&mpt1, &mpt2, &mpt3, p);
Packit 6c4009
	  __dvd (&mpsm, &mpt3, &mpt1, p);
Packit 6c4009
	  __cpy (&mpt1, &mpsm, p);
Packit 6c4009
	}
Packit 6c4009
      __mpsqrt (&mpsm, &mps, p);
Packit 6c4009
      mps.d[0] = X[0];
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Evaluate a truncated power series for Atan(s).  */
Packit 6c4009
  n = __atan_np[p];
Packit 6c4009
  mptwoim1.d[1] = __atan_twonm1[p].d;
Packit 6c4009
  __dvd (&mpsm, &mptwoim1, &mpt, p);
Packit 6c4009
  for (i = n - 1; i > 1; i--)
Packit 6c4009
    {
Packit 6c4009
      mptwoim1.d[1] -= 2;
Packit 6c4009
      __dvd (&mpsm, &mptwoim1, &mpt1, p);
Packit 6c4009
      __mul (&mpsm, &mpt, &mpt2, p);
Packit 6c4009
      __sub (&mpt1, &mpt2, &mpt, p);
Packit 6c4009
    }
Packit 6c4009
  __mul (&mps, &mpt, &mpt1, p);
Packit 6c4009
  __sub (&mps, &mpt1, &mpt, p);
Packit 6c4009
Packit 6c4009
  /* Compute Atan(x).  */
Packit 6c4009
  mptwoim1.d[1] = 1 << m;
Packit 6c4009
  __mul (&mptwoim1, &mpt, y, p);
Packit 6c4009
}