Beispiel #1
0
/* evaluates tan x for |x| <= pi.
   A return value of 0 indicates
   that x = +/- pi/2 within
   small tolerances, so that tan x
   cannot be reliable computed */
char
_tan(
  floatnum x,
  int digits)
{
  signed char sgn;

  sgn = float_getsign(x);
  float_abs(x);
  if (float_cmp(x, &cPiDiv2) > 0)
  {
    float_sub(x, &cPi, x, digits+1);
    sgn = -sgn;
  }
  if (float_cmp(x, &cPiDiv4) <= 0)
    _tanltPiDiv4(x, digits);
  else
  {
    float_sub(x, &cPiDiv2, x, digits+1);
    if (float_iszero(x) || float_getexponent(x) < -digits)
      return 0;
    _tanltPiDiv4(x, digits);
    float_reciprocal(x, digits);
  }
  float_setsign(x, sgn);
  return 1;
}
Beispiel #2
0
char
binetasymptotic(floatnum x,
                int digits)
{
  floatstruct recsqr;
  floatstruct sum;
  floatstruct smd;
  floatstruct pwr;
  int i, workprec;

  if (float_getexponent(x) >= digits)
  {
    /* if x is very big, ln(gamma(x)) is
    dominated by x*ln x and the Binet function
    does not contribute anything substantial to
    the final result */
    float_setzero(x);
    return 1;
  }
  float_create(&recsqr);
  float_create(&sum);
  float_create(&smd);
  float_create(&pwr);

  float_copy(&pwr, &c1, EXACT);
  float_setzero(&sum);
  float_div(&smd, &c1, &c12, digits+1);
  workprec = digits - 2*float_getexponent(x)+3;
  i = 1;
  if (workprec > 0)
  {
    float_mul(&recsqr, x, x, workprec);
    float_reciprocal(&recsqr, workprec);
    while (float_getexponent(&smd) > -digits-1
           && ++i <= MAXBERNOULLIIDX)
    {
      workprec = digits + float_getexponent(&smd) + 3;
      float_add(&sum, &sum, &smd, digits+1);
      float_mul(&pwr, &recsqr, &pwr, workprec);
      float_muli(&smd, &cBernoulliDen[i-1], 2*i*(2*i-1), workprec);
      float_div(&smd, &pwr, &smd, workprec);
      float_mul(&smd, &smd, &cBernoulliNum[i-1], workprec);
    }
  }
  else
    /* sum reduces to the first summand*/
    float_move(&sum, &smd);
  if (i > MAXBERNOULLIIDX)
      /* x was not big enough for the asymptotic
    series to converge sufficiently */
    float_setnan(x);
  else
    float_div(x, &sum, x, digits);
  float_free(&pwr);
  float_free(&smd);
  float_free(&sum);
  float_free(&recsqr);
  return i <= MAXBERNOULLIIDX;
}
Beispiel #3
0
static char
_pochhammer_si(
  floatnum x,
  int n,
  int digits)
{
  /* this extends the rising Pochhammer symbol to negative integer offsets
     following the formula pochhammer(x,n-1) = pochhammer(x,n)/(x-n+1) */

  if (n >= 0)
    return _pochhammer_su(x, n, digits);
  return float_addi(x, x, n, digits)
         && _pochhammer_su(x, -n, digits)
         && float_reciprocal(x, digits);
}
Beispiel #4
0
/* evaluates arctan x for all x. The result is in the
   range -pi/2 < result < pi/2
   relative error for a 100 digit result is 9e-100 */
void
_arctan(
  floatnum x,
  int digits)
{
  signed char sgn;

  if (float_abscmp(x, &c1) > 0)
  {
    sgn = float_getsign(x);
    float_abs(x);
    float_reciprocal(x, digits);
    _arctanlt1(x, digits);
    float_sub(x, &cPiDiv2, x, digits+1);
    float_setsign(x, sgn);
  }
  else
    _arctanlt1(x, digits);
}