(root)/
glibc-2.38/
sysdeps/
ieee754/
dbl-64/
e_asin.c
       1  /*
       2   * IBM Accurate Mathematical Library
       3   * written by International Business Machines Corp.
       4   * Copyright (C) 2001-2023 Free Software Foundation, Inc.
       5   *
       6   * This program is free software; you can redistribute it and/or modify
       7   * it under the terms of the GNU Lesser General Public License as published by
       8   * the Free Software Foundation; either version 2.1 of the License, or
       9   * (at your option) any later version.
      10   *
      11   * This program is distributed in the hope that it will be useful,
      12   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14   * GNU Lesser General Public License for more details.
      15   *
      16   * You should have received a copy of the GNU Lesser General Public License
      17   * along with this program; if not, see <https://www.gnu.org/licenses/>.
      18   */
      19  /******************************************************************/
      20  /*     MODULE_NAME:uasncs.c                                       */
      21  /*                                                                */
      22  /*     FUNCTIONS: uasin                                           */
      23  /*                uacos                                           */
      24  /* FILES NEEDED: dla.h endian.h mydefs.h  usncs.h                 */
      25  /*               sincos.tbl  asincos.tbl  powtwo.tbl root.tbl     */
      26  /*                                                                */
      27  /******************************************************************/
      28  #include "endian.h"
      29  #include "mydefs.h"
      30  #include "asincos.tbl"
      31  #include "root.tbl"
      32  #include "powtwo.tbl"
      33  #include "uasncs.h"
      34  #include <float.h>
      35  #include <math.h>
      36  #include <math_private.h>
      37  #include <math-underflow.h>
      38  #include <libm-alias-finite.h>
      39  
      40  #ifndef SECTION
      41  # define SECTION
      42  #endif
      43  
      44  /* asin with max ULP of ~0.516 based on random sampling.  */
      45  double
      46  SECTION
      47  __ieee754_asin(double x){
      48    double x2,xx,res1,p,t,res,r,cor,cc,y,c,z;
      49    mynumber u,v;
      50    int4 k,m,n;
      51  
      52    u.x = x;
      53    m = u.i[HIGH_HALF];
      54    k = 0x7fffffff&m;              /* no sign */
      55  
      56    if (k < 0x3e500000)
      57      {
      58        math_check_force_underflow (x);
      59        return x;  /* for x->0 => sin(x)=x */
      60      }
      61    /*----------------------2^-26 <= |x| < 2^ -3    -----------------*/
      62    else
      63    if (k < 0x3fc00000) {
      64      x2 = x*x;
      65      t = (((((f6*x2 + f5)*x2 + f4)*x2 + f3)*x2 + f2)*x2 + f1)*(x2*x);
      66      res = x+t;         /*  res=arcsin(x) according to Taylor series  */
      67      /* Max ULP is 0.513.  */
      68      return res;
      69    }
      70    /*---------------------0.125 <= |x| < 0.5 -----------------------------*/
      71    else if (k < 0x3fe00000) {
      72      if (k<0x3fd00000) n = 11*((k&0x000fffff)>>15);
      73      else n = 11*((k&0x000fffff)>>14)+352;
      74      if (m>0) xx = x - asncs.x[n];
      75      else xx = -x - asncs.x[n];
      76      t = asncs.x[n+1]*xx;
      77      p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
      78       +xx*asncs.x[n+6]))))+asncs.x[n+7];
      79      t+=p;
      80      res =asncs.x[n+8] +t;
      81      /* Max ULP is 0.524.  */
      82      return (m>0)?res:-res;
      83    }    /*   else  if (k < 0x3fe00000)    */
      84    /*-------------------- 0.5 <= |x| < 0.75 -----------------------------*/
      85    else
      86    if (k < 0x3fe80000) {
      87      n = 1056+((k&0x000fe000)>>11)*3;
      88      if (m>0) xx = x - asncs.x[n];
      89      else xx = -x - asncs.x[n];
      90      t = asncs.x[n+1]*xx;
      91      p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
      92  	   +xx*(asncs.x[n+6]+xx*asncs.x[n+7])))))+asncs.x[n+8];
      93      t+=p;
      94      res =asncs.x[n+9] +t;
      95      /* Max ULP is 0.505.  */
      96      return (m>0)?res:-res;
      97    }    /*   else  if (k < 0x3fe80000)    */
      98    /*--------------------- 0.75 <= |x|< 0.921875 ----------------------*/
      99    else
     100    if (k < 0x3fed8000) {
     101      n = 992+((k&0x000fe000)>>13)*13;
     102      if (m>0) xx = x - asncs.x[n];
     103      else xx = -x - asncs.x[n];
     104      t = asncs.x[n+1]*xx;
     105      p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+xx*(asncs.x[n+5]
     106       +xx*(asncs.x[n+6]+xx*(asncs.x[n+7]+xx*asncs.x[n+8]))))))+asncs.x[n+9];
     107      t+=p;
     108      res =asncs.x[n+10] +t;
     109      /* Max ULP is 0.505.  */
     110      return (m>0)?res:-res;
     111    }    /*   else  if (k < 0x3fed8000)    */
     112    /*-------------------0.921875 <= |x| < 0.953125 ------------------------*/
     113    else
     114    if (k < 0x3fee8000) {
     115      n = 884+((k&0x000fe000)>>13)*14;
     116      if (m>0) xx = x - asncs.x[n];
     117      else xx = -x - asncs.x[n];
     118      t = asncs.x[n+1]*xx;
     119      p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
     120  		      xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
     121  		      +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
     122  		      xx*asncs.x[n+9])))))))+asncs.x[n+10];
     123      t+=p;
     124      res =asncs.x[n+11] +t;
     125      /* Max ULP is 0.505.  */
     126      return (m>0)?res:-res;
     127    }    /*   else  if (k < 0x3fee8000)    */
     128  
     129    /*--------------------0.953125 <= |x| < 0.96875 ------------------------*/
     130    else
     131    if (k < 0x3fef0000) {
     132      n = 768+((k&0x000fe000)>>13)*15;
     133      if (m>0) xx = x - asncs.x[n];
     134      else xx = -x - asncs.x[n];
     135      t = asncs.x[n+1]*xx;
     136      p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
     137  			 xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
     138  			 +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
     139  		    xx*(asncs.x[n+9]+xx*asncs.x[n+10]))))))))+asncs.x[n+11];
     140      t+=p;
     141      res =asncs.x[n+12] +t;
     142      /* Max ULP is 0.505.  */
     143      return (m>0)?res:-res;
     144    }    /*   else  if (k < 0x3fef0000)    */
     145    /*--------------------0.96875 <= |x| < 1 --------------------------------*/
     146    else
     147    if (k<0x3ff00000)  {
     148      z = 0.5*((m>0)?(1.0-x):(1.0+x));
     149      v.x=z;
     150      k=v.i[HIGH_HALF];
     151      t=inroot[(k&0x001fffff)>>14]*powtwo[511-(k>>21)];
     152      r=1.0-t*t*z;
     153      t = t*(rt0+r*(rt1+r*(rt2+r*rt3)));
     154      c=t*z;
     155      t=c*(1.5-0.5*t*c);
     156      y=(c+t24)-t24;
     157      cc = (z-y*y)/(t+y);
     158      p=(((((f6*z+f5)*z+f4)*z+f3)*z+f2)*z+f1)*z;
     159      cor = (hp1.x - 2.0*cc)-2.0*(y+cc)*p;
     160      res1 = hp0.x - 2.0*y;
     161      res =res1 + cor;
     162      /* Max ULP is 0.5015.  */
     163      return (m>0)?res:-res;
     164    }    /*   else  if (k < 0x3ff00000)    */
     165    /*---------------------------- |x|>=1 -------------------------------*/
     166    else if (k==0x3ff00000 && u.i[LOW_HALF]==0) return (m>0)?hp0.x:-hp0.x;
     167    else
     168      return (x - x) / (x - x);
     169  }
     170  #ifndef __ieee754_asin
     171  libm_alias_finite (__ieee754_asin, __asin)
     172  #endif
     173  
     174  /*******************************************************************/
     175  /*                                                                 */
     176  /*         End of arcsine,  below is arccosine                     */
     177  /*                                                                 */
     178  /*******************************************************************/
     179  
     180  /* acos with max ULP of ~0.523 based on random sampling.  */
     181  double
     182  SECTION
     183  __ieee754_acos(double x)
     184  {
     185    double x2,xx,res1,p,t,res,r,cor,cc,y,c,z;
     186    mynumber u,v;
     187    int4 k,m,n;
     188    u.x = x;
     189    m = u.i[HIGH_HALF];
     190    k = 0x7fffffff&m;
     191    /*-------------------  |x|<2.77556*10^-17 ----------------------*/
     192    if (k < 0x3c880000) return hp0.x;
     193  
     194    /*-----------------  2.77556*10^-17 <= |x| < 2^-3 --------------*/
     195    else
     196    if (k < 0x3fc00000) {
     197      x2 = x*x;
     198      t = (((((f6*x2 + f5)*x2 + f4)*x2 + f3)*x2 + f2)*x2 + f1)*(x2*x);
     199      r=hp0.x-x;
     200      cor=(((hp0.x-r)-x)+hp1.x)-t;
     201      res = r+cor;
     202      /* Max ULP is 0.502.  */
     203      return res;
     204    }    /*   else  if (k < 0x3fc00000)    */
     205    /*----------------------  0.125 <= |x| < 0.5 --------------------*/
     206    else
     207    if (k < 0x3fe00000) {
     208      if (k<0x3fd00000) n = 11*((k&0x000fffff)>>15);
     209      else n = 11*((k&0x000fffff)>>14)+352;
     210      if (m>0) xx = x - asncs.x[n];
     211      else xx = -x - asncs.x[n];
     212      t = asncs.x[n+1]*xx;
     213      p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
     214  		   xx*(asncs.x[n+5]+xx*asncs.x[n+6]))))+asncs.x[n+7];
     215      t+=p;
     216      y = (m>0)?(hp0.x-asncs.x[n+8]):(hp0.x+asncs.x[n+8]);
     217      t = (m>0)?(hp1.x-t):(hp1.x+t);
     218      res = y+t;
     219     /* Max ULP is 0.51.  */
     220      return res;
     221    }    /*   else  if (k < 0x3fe00000)    */
     222  
     223    /*--------------------------- 0.5 <= |x| < 0.75 ---------------------*/
     224    else
     225    if (k < 0x3fe80000) {
     226      n = 1056+((k&0x000fe000)>>11)*3;
     227      if (m>0) {xx = x - asncs.x[n]; }
     228      else {xx = -x - asncs.x[n]; }
     229      t = asncs.x[n+1]*xx;
     230      p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
     231  		   xx*(asncs.x[n+5]+xx*(asncs.x[n+6]+
     232  		   xx*asncs.x[n+7])))))+asncs.x[n+8];
     233      t+=p;
     234     y = (m>0)?(hp0.x-asncs.x[n+9]):(hp0.x+asncs.x[n+9]);
     235     t = (m>0)?(hp1.x-t):(hp1.x+t);
     236     res = y+t;
     237     /* Max ULP is 0.523 based on random sampling.  */
     238     return res;
     239    }    /*   else  if (k < 0x3fe80000)    */
     240  
     241  /*------------------------- 0.75 <= |x| < 0.921875 -------------*/
     242    else
     243    if (k < 0x3fed8000) {
     244      n = 992+((k&0x000fe000)>>13)*13;
     245      if (m>0) {xx = x - asncs.x[n]; }
     246      else {xx = -x - asncs.x[n]; }
     247      t = asncs.x[n+1]*xx;
     248      p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
     249  		      xx*(asncs.x[n+5]+xx*(asncs.x[n+6]+xx*(asncs.x[n+7]+
     250  		      xx*asncs.x[n+8]))))))+asncs.x[n+9];
     251      t+=p;
     252      y = (m>0)?(hp0.x-asncs.x[n+10]):(hp0.x+asncs.x[n+10]);
     253      t = (m>0)?(hp1.x-t):(hp1.x+t);
     254      res = y+t;
     255     /* Max ULP is 0.523 based on random sampling.  */
     256      return res;
     257    }    /*   else  if (k < 0x3fed8000)    */
     258  
     259  /*-------------------0.921875 <= |x| < 0.953125 ------------------*/
     260    else
     261    if (k < 0x3fee8000) {
     262      n = 884+((k&0x000fe000)>>13)*14;
     263      if (m>0) {xx = x - asncs.x[n]; }
     264      else {xx = -x - asncs.x[n]; }
     265      t = asncs.x[n+1]*xx;
     266      p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
     267  		   xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
     268  		   +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+
     269  		   xx*asncs.x[n+9])))))))+asncs.x[n+10];
     270      t+=p;
     271      y = (m>0)?(hp0.x-asncs.x[n+11]):(hp0.x+asncs.x[n+11]);
     272      t = (m>0)?(hp1.x-t):(hp1.x+t);
     273      res = y+t;
     274     /* Max ULP is 0.523 based on random sampling.  */
     275      return res;
     276    }    /*   else  if (k < 0x3fee8000)    */
     277  
     278    /*--------------------0.953125 <= |x| < 0.96875 ----------------*/
     279    else
     280    if (k < 0x3fef0000) {
     281      n = 768+((k&0x000fe000)>>13)*15;
     282      if (m>0) {xx = x - asncs.x[n]; }
     283      else {xx = -x - asncs.x[n]; }
     284      t = asncs.x[n+1]*xx;
     285      p=xx*xx*(asncs.x[n+2]+xx*(asncs.x[n+3]+xx*(asncs.x[n+4]+
     286  	    xx*(asncs.x[n+5]+xx*(asncs.x[n+6]
     287  	    +xx*(asncs.x[n+7]+xx*(asncs.x[n+8]+xx*(asncs.x[n+9]+
     288  	    xx*asncs.x[n+10]))))))))+asncs.x[n+11];
     289      t+=p;
     290      y = (m>0)?(hp0.x-asncs.x[n+12]):(hp0.x+asncs.x[n+12]);
     291     t = (m>0)?(hp1.x-t):(hp1.x+t);
     292     res = y+t;
     293     /* Max ULP is 0.523 based on random sampling.  */
     294     return res;
     295    }    /*   else  if (k < 0x3fef0000)    */
     296    /*-----------------0.96875 <= |x| < 1 ---------------------------*/
     297  
     298    else
     299    if (k<0x3ff00000)  {
     300      z = 0.5*((m>0)?(1.0-x):(1.0+x));
     301      v.x=z;
     302      k=v.i[HIGH_HALF];
     303      t=inroot[(k&0x001fffff)>>14]*powtwo[511-(k>>21)];
     304      r=1.0-t*t*z;
     305      t = t*(rt0+r*(rt1+r*(rt2+r*rt3)));
     306      c=t*z;
     307      t=c*(1.5-0.5*t*c);
     308      y = (t27*c+c)-t27*c;
     309      cc = (z-y*y)/(t+y);
     310      p=(((((f6*z+f5)*z+f4)*z+f3)*z+f2)*z+f1)*z;
     311      if (m<0) {
     312        cor = (hp1.x - cc)-(y+cc)*p;
     313        res1 = hp0.x - y;
     314        res =res1 + cor;
     315        /* Max ULP is 0.501.  */
     316        return (res+res);
     317      }
     318      else {
     319        cor = cc+p*(y+cc);
     320        res = y + cor;
     321        /* Max ULP is 0.515.  */
     322        return (res+res);
     323      }
     324    }    /*   else  if (k < 0x3ff00000)    */
     325  
     326    /*---------------------------- |x|>=1 -----------------------*/
     327    else
     328    if (k==0x3ff00000 && u.i[LOW_HALF]==0) return (m>0)?0:2.0*hp0.x;
     329    else
     330      return (x - x) / (x - x);
     331  }
     332  #ifndef __ieee754_acos
     333  libm_alias_finite (__ieee754_acos, __acos)
     334  #endif