/* y=0 is not permitted if x<=0. No error messages are given. */ void __mpatan2(mp_no *y, mp_no *x, mp_no *z, int p) { static const double ZERO = 0.0, ONE = 1.0; mp_no mpone = {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.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.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}}; mp_no mpt1,mpt2,mpt3; if (X[0] <= ZERO) { mpone.e = 1; mpone.d[0] = mpone.d[1] = ONE; __dvd(x,y,&mpt1,p); __mul(&mpt1,&mpt1,&mpt2,p); if (mpt1.d[0] != ZERO) mpt1.d[0] = ONE; __add(&mpt2,&mpone,&mpt3,p); __mpsqrt(&mpt3,&mpt2,p); __add(&mpt1,&mpt2,&mpt3,p); mpt3.d[0]=Y[0]; __mpatan(&mpt3,&mpt1,p); __add(&mpt1,&mpt1,z,p); } else { __dvd(y,x,&mpt1,p); __mpatan(&mpt1,z,p); } return; }
void SECTION __mpatan(mp_no *x, mp_no *y, int p) { int i,m,n; double dx; mp_no mpone = {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.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.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}}, mptwo = {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.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.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}}, mptwoim1 = {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.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.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}}; mp_no mps,mpsm,mpt,mpt1,mpt2,mpt3; /* Choose m and initiate mpone, mptwo & mptwoim1 */ if (EX>0) m=7; else if (EX<0) m=0; else { __mp_dbl(x,&dx,p); dx=ABS(dx); for (m=6; m>0; m--) {if (dx>__atan_xm[m].d) break;} } mpone.e = mptwo.e = mptwoim1.e = 1; mpone.d[0] = mpone.d[1] = mptwo.d[0] = mptwoim1.d[0] = ONE; mptwo.d[1] = TWO; /* Reduce x m times */ __mul(x,x,&mpsm,p); if (m==0) __cpy(x,&mps,p); else { for (i=0; i<m; i++) { __add(&mpone,&mpsm,&mpt1,p); __mpsqrt(&mpt1,&mpt2,p); __add(&mpt2,&mpt2,&mpt1,p); __add(&mptwo,&mpsm,&mpt2,p); __add(&mpt1,&mpt2,&mpt3,p); __dvd(&mpsm,&mpt3,&mpt1,p); __cpy(&mpt1,&mpsm,p); } __mpsqrt(&mpsm,&mps,p); mps.d[0] = X[0]; } /* Evaluate a truncated power series for Atan(s) */ n=__atan_np[p]; mptwoim1.d[1] = __atan_twonm1[p].d; __dvd(&mpsm,&mptwoim1,&mpt,p); for (i=n-1; i>1; i--) { mptwoim1.d[1] -= TWO; __dvd(&mpsm,&mptwoim1,&mpt1,p); __mul(&mpsm,&mpt,&mpt2,p); __sub(&mpt1,&mpt2,&mpt,p); } __mul(&mps,&mpt,&mpt1,p); __sub(&mps,&mpt1,&mpt,p); /* Compute Atan(x) */ mptwoim1.d[1] = __atan_twom[m].d; __mul(&mptwoim1,&mpt,y,p); return; }