Пример #1
0
static char
_lngamma_prim(
  floatnum x,
  floatnum revfactor,
  int* infinity,
  int digits)
{
  floatstruct tmp;
  char result;
  char odd;

  *infinity = 0;
  if (float_getsign(x) > 0)
    return _lngamma_prim_xgt0(x, revfactor, digits);
  float_copy(revfactor, x, digits + 2);
  float_sub(x, &c1, x, digits+2);
  float_create(&tmp);
  result = _lngamma_prim_xgt0(x, &tmp, digits);
  if (result)
  {
    float_neg(x);
    odd = float_isodd(revfactor);
    _sinpix(revfactor, digits);
    if (float_iszero(revfactor))
    {
      *infinity = 1;
      float_setinteger(revfactor, odd? -1 : 1);
    }
    else
      float_mul(&tmp, &tmp, &cPi, digits+2);
    float_div(revfactor, revfactor, &tmp, digits+2);
  }
  float_free(&tmp);
  return result;
}
Пример #2
0
static Error
_pack2frac(
  floatnum x,
  p_ext_seq_desc n,
  int digits)
{
  floatstruct tmp;
  int exp;
  Error result;

  n->seq.digits -= n->seq.trailing0;
  n->seq.trailing0 = 0;
  switch(n->seq.base)
  {
  case IO_BASE_NAN:
    float_setnan(x);
    break;
  case IO_BASE_ZERO:
    float_setzero(x);
    break;
  default:
    if ((result = _pack2int(x, n)) != Success)
      return result;
    float_create(&tmp);
    float_setinteger(&tmp, n->seq.base);
    _raiseposi(&tmp, &exp, n->seq.digits, digits+2);
    float_div(x, x, &tmp, digits + 2);
    float_setexponent(x, float_getexponent(x) - exp);
    float_free(&tmp);
  }
  n->seq.digits += n->seq.trailing0;
  return Success;
}
Пример #3
0
static void
_setunsigned(
  floatnum f,
  unsigned value)
{
  float_setinteger(f, value);
  if ((int)value < 0)
    float_add(f, f, &cUnsignedBound, EXACT);
}
Пример #4
0
Error
pack2floatnum(
  floatnum x,
  p_number_desc n)
{
  floatstruct tmp;
  int digits;
  int saveerr;
  int saverange;
  Error result;
  signed char base;

  if ((result = _pack2int(x, &n->intpart)) != Success)
    return result;
  if (float_isnan(x))
    return Success;
  saveerr = float_geterror();
  saverange = float_setrange(MAXEXP);
  float_create(&tmp);
  float_move(&tmp, x);
  float_setzero(x);
  digits = DECPRECISION - float_getexponent(&tmp);
  if (digits <= 0
      || (result = _pack2frac(x, &n->fracpart, digits)) == Success)
    float_add(x, x, &tmp, DECPRECISION);
  if (result != Success)
    return result;
  if ((!float_getlength(x)) == 0) /* no zero, no NaN? */
  {
    base = n->prefix.base;
    float_setinteger(&tmp, base);
    if (n->exp >= 0)
    {
      _raiseposi_(&tmp, n->exp, DECPRECISION + 2);
      float_mul(x, x, &tmp, DECPRECISION + 2);
    }
    else
    {
      _raiseposi_(&tmp, -n->exp, DECPRECISION + 2);
      float_div(x, x, &tmp, DECPRECISION + 2);
    }
  }
  float_free(&tmp);
  float_setsign(x, n->prefix.sign == IO_SIGN_COMPLEMENT? -1 : n->prefix.sign);
  float_geterror();
  float_seterror(saveerr);
  float_setrange(saverange);
  if (!float_isvalidexp(float_getexponent(x)))
    float_setnan(x);
  return float_isnan(x)? IOExpOverflow : Success;
}
Пример #5
0
static int
_extractexp(
  floatnum x,
  int scale,
  signed char base)
{
  floatstruct pwr;
  floatstruct fbase;
  int decprec;
  int pwrexp;
  int exp;
  int logbase;

  (void)scale;

  logbase = lgbase(base);
  decprec = DECPRECISION + 3;
  exp = (int)(aprxlog10fn(x) * 3.321928095f);
  if (float_getexponent(x) < 0)
    exp -= 3;
  exp /= logbase;
  if (exp != 0)
  {
    float_create(&fbase);
    float_setinteger(&fbase, base);
    float_create(&pwr);
    float_copy(&pwr, &fbase, EXACT);
    _raiseposi(&pwr, &pwrexp, exp < 0? -exp : exp, decprec);
    if (float_getexponent(x) < 0)
    {
      float_addexp(x, pwrexp);
      float_mul(x, x, &pwr, decprec);
    }
    else
    {
      float_addexp(x, -pwrexp);
      float_div(x, x, &pwr, decprec);
    }
    float_free(&pwr);
    float_free(&fbase);
  }
  exp += _checkbounds(x, decprec, base);
  return exp;
}
Пример #6
0
static void
_scale2int(
  floatnum x,
  int scale,
  signed char base)
{
  floatstruct pwr;
  int pwrexp;

  (void)scale;

  if (scale != 0)
  {
    float_create(&pwr);
    float_setinteger(&pwr, base);
    _raiseposi(&pwr, &pwrexp, scale, DECPRECISION+4);
    float_mul(x, x, &pwr, DECPRECISION+4);
    float_addexp(x, pwrexp);
    float_free(&pwr);
  }
  float_roundtoint(x, TONEAREST);
}
Пример #7
0
char
float_lg(
  floatnum x,
  int digits)
{
  floatstruct tmp;
  int expx;

  if (!chckmathparam(x, digits))
    return 0;
  if (float_getsign(x) <= 0)
    return _seterror(x, OutOfDomain);
  float_create(&tmp);
  expx = float_getexponent(x);
  float_setexponent(x, 0);
  _ln(x, digits);
  float_div(x, x, &cLn10, digits);
  float_setinteger(&tmp, expx);
  float_add(x, x, &tmp, digits);
  float_free(&tmp);
  return 1;
}
Пример #8
0
void
floatmath_init()
{
  int i, save;
  floatnum_init();

  save = float_setprecision(MAXDIGITS);
  float_create(&c1);
  float_setinteger(&c1, 1);
  float_create(&c2);
  float_setinteger(&c2, 2);
  float_create(&c3);
  float_setinteger(&c3, 3);
  float_create(&c12);
  float_setinteger(&c12, 12);
  float_create(&c16);
  float_setinteger(&c16, 16);
  float_create(&cMinus1);
  float_setinteger(&cMinus1, -1);
  float_create(&cMinus20);
  float_setinteger(&cMinus20, -20);
  float_create(&c1Div2);
  float_setscientific(&c1Div2, ".5", NULLTERMINATED);
  float_create(&cExp);
  float_setscientific(&cExp, sExp, NULLTERMINATED);
  float_create(&cLn2);
  float_setscientific(&cLn2, sLn2, NULLTERMINATED);
  float_create(&cLn3);
  float_setscientific(&cLn3, sLn3, NULLTERMINATED);
  float_create(&cLn7);
  float_setscientific(&cLn7, sLn7, NULLTERMINATED);
  float_create(&cLn10);
  float_setscientific(&cLn10, sLn10, NULLTERMINATED);
  float_create(&cPhi);
  float_setscientific(&cPhi, sPhi, NULLTERMINATED);
  float_create(&cPi);
  float_setscientific(&cPi, sPi, NULLTERMINATED);
  float_create(&cPiDiv2);
  float_setscientific(&cPiDiv2, sPiDiv2, NULLTERMINATED);
  float_create(&cPiDiv4);
  float_setscientific(&cPiDiv4, sPiDiv4, NULLTERMINATED);
  float_create(&c2Pi);
  float_setscientific(&c2Pi, s2Pi, NULLTERMINATED);
  float_create(&c1DivPi);
  float_setscientific(&c1DivPi, s1DivPi, NULLTERMINATED);
  float_create(&cSqrtPi);
  float_setscientific(&cSqrtPi, sSqrtPi, NULLTERMINATED);
  float_create(&cLnSqrt2PiMinusHalf);
  float_setscientific(&cLnSqrt2PiMinusHalf, sLnSqrt2PiMinusHalf,
                      NULLTERMINATED);
  float_create(&c1DivSqrtPi);
  float_setscientific(&c1DivSqrtPi, s1DivSqrtPi, NULLTERMINATED);
  float_create(&c2DivSqrtPi);
  float_setscientific(&c2DivSqrtPi, s2DivSqrtPi, NULLTERMINATED);
  float_create(&cMinus0_4);
  float_setscientific(&cMinus0_4, "-.4", NULLTERMINATED);
  for (i = -1; ++i < MAXBERNOULLIIDX;)
  {
    float_create(&cBernoulliNum[i]);
    float_create(&cBernoulliDen[i]);
    float_setscientific(&cBernoulliNum[i], sBernoulli[2*i], NULLTERMINATED);
    float_setscientific(&cBernoulliDen[i], sBernoulli[2*i+1], NULLTERMINATED);
  }
  float_create(&cUnsignedBound);
  float_copy(&cUnsignedBound, &c1, EXACT);
  for (i = -1; ++i < 2*(int)sizeof(unsigned);)
    float_mul(&cUnsignedBound, &c16, &cUnsignedBound, EXACT);
  for (i = -1; ++i < MAXERFCIDX;)
    float_create(&erfccoeff[i]);
  float_create(&erfcalpha);
  float_create(&erfcalphasqr);
  float_create(&erfct2);
  float_create(&erfct3);
  float_setprecision(save);
}