Exemple #1
0
char
_doshift(
  floatnum dest,
  cfloatnum x,
  cfloatnum shift,
  char right)
{
  int ishift;
  t_longint lx;

  if (float_isnan(shift))
    return _seterror(dest, NoOperand);
  if (!float_isinteger(shift))
    return _seterror(dest, OutOfDomain);
  if(!_cvtlogic(&lx, x))
    return 0;
  if (float_iszero(shift))
  {
    float_copy(dest, x, EXACT);
    return 1;
  }
  ishift = float_asinteger(shift);
  if (ishift == 0)
    ishift = (3*LOGICRANGE) * float_getsign(shift);
  if (!right)
    ishift = -ishift;
  if (ishift > 0)
    _shr(&lx, ishift);
  else
    _shl(&lx, -ishift);
  _logic2floatnum(dest, &lx);
  return 1;
}
Exemple #2
0
char
float_cosminus1(
  floatnum x,
  int digits)
{
  if (!chckmathparam(x, digits))
    return 0;
  if (!_trigreduce(x, digits))
    return _seterror(x, EvalUnstable);
  return _cosminus1(x, digits)? 1 : _seterror(x, Underflow);
}
Exemple #3
0
char
float_power10(
  floatnum x,
  int digits)
{
  signed char sign;

  if (!chckmathparam(x, digits))
    return 0;
  sign = float_getsign(x);
  if (_power10(x, digits))
    return 1;
  return sign > 0? _seterror(x, Overflow) : _seterror(x, Underflow);
}
Exemple #4
0
char
_lngamma(
  floatnum x,
  int digits)
{
  floatstruct factor;
  int infinity;
  char result;

  if (float_cmp(x, &c1) == 0 || float_cmp(x, &c2) == 0)
    return _setzero(x);
  float_create(&factor);
  result = _lngamma_prim(x, &factor, &infinity, digits)
           && infinity == 0;
  if (result)
  {
    float_abs(&factor);
    _ln(&factor, digits + 1);
    result = float_sub(x, x, &factor, digits+1);
  }
  float_free(&factor);
  if (infinity != 0)
    return _seterror(x, ZeroDivide);
  if (!result)
    float_setnan(x);
  return result;
}
Exemple #5
0
char
float_coshminus1(
  floatnum x,
  int digits)
{
  int expx;

  if (!chckmathparam(x, digits))
    return 0;
  expx = float_getexponent(x);
  if (_coshminus1(x, digits))
    return 1;
  if (expx < 0)
    return _seterror(x, Underflow);
  return _seterror(x, Overflow);
}
Exemple #6
0
char
_gamma(
  floatnum x,
  int digits)
{
  floatstruct tmp;
  int infinity;
  char result;

  if (float_cmp(&cMinus20, x) > 0)
  {
    float_create(&tmp);
    result = _lngamma_prim(x, &tmp, &infinity, digits)
             && infinity == 0
             && _exp(x, digits)
             && float_div(x, x, &tmp, digits + 1);
    float_free(&tmp);
    if (infinity != 0)
      return _seterror(x, ZeroDivide);
    if (!result)
      float_setnan(x);
    return result;
  }
  return _gammagtminus20(x, digits);
}
Exemple #7
0
char
float_exp(
  floatnum x,
  int digits)
{
  signed char sgn;

  if (!chckmathparam(x, digits))
    return 0;
  sgn = float_getsign(x);
  if (_exp(x, digits))
    return 1;
  if (sgn < 0)
    return _seterror(x, Underflow);
  return _seterror(x, Overflow);
}
Exemple #8
0
char
float_gamma(
  floatnum x,
  int digits)
{
  signed char sign;
  char result;

  if (!chckmathparam(x, digits))
    return 0;
  sign = float_getsign(x);
  if (float_isinteger(x))
  {
    if (sign <= 0)
      return _seterror(x, ZeroDivide);
    result = _gammaint(x, digits);
  }
  else if (float_getlength(x) - float_getexponent(x) == 2
           && float_getdigit(x, float_getlength(x) - 1) == 5)
    result = _gamma0_5(x, digits);
  else
    result = _gamma(x, digits);
  if (!result)
  {
    if (sign < 0)
      float_seterror(Underflow);
    else
      float_seterror(Overflow);
    float_setnan(x);
  }
  return result;
}
Exemple #9
0
char
float_raise(
  floatnum power,
  cfloatnum base,
  cfloatnum exponent,
  int digits)
{
  signed char sgn;

  if (float_isnan(exponent) || float_isnan(base))
    return _seterror(power, NoOperand);
  if (digits <= 0 || digits > MATHPRECISION)
    return _seterror(power, InvalidPrecision);
  if (float_iszero(base))
  {
    switch(float_getsign(exponent))
    {
    case 0:
      return _seterror(power, OutOfDomain);
    case -1:
      return _seterror(power, ZeroDivide);
    }
    return _setzero(power);
  }
  sgn = float_getsign(base);
  if (sgn < 0)
  {
    if (!float_isinteger(exponent))
      return _seterror(power, OutOfDomain);
    if ((float_getdigit(exponent, float_getexponent(exponent)) & 1) == 0)
      sgn = 1;
  }
  float_copy(power, base, digits+1);
  float_abs(power);
  if (!_raise(power, exponent, digits))
  {
    float_seterror(Overflow);
    if (float_getexponent(base) * float_getsign(exponent) < 0)
      float_seterror(Underflow);
    return _setnan(power);
  }
  float_setsign(power, sgn);
  return 1;
}
Exemple #10
0
char
float_ln(floatnum x, int digits)
{
  if (!chckmathparam(x, digits))
    return 0;
  if (float_getsign(x) <= 0)
    return _seterror(x, OutOfDomain);
  _ln(x, digits);
  return 1;
}
Exemple #11
0
char
float_lngamma(
  floatnum x,
  int digits)
{
  if (!x)
    return _seterror(x, OutOfDomain);
  return chckmathparam(x, digits) && _lngamma(x, digits)?
          1 : _setnan(x);
}
Exemple #12
0
char
float_expminus1(
  floatnum x,
  int digits)
{
  if (!chckmathparam(x, digits))
    return 0;
  if (_expminus1(x, digits))
    return 1;
  return _seterror(x, Overflow);
}
Exemple #13
0
char
float_sinh(
  floatnum x,
  int digits)
{
  if (!chckmathparam(x, digits))
    return 0;
  if (_sinh(x, digits))
    return 1;
  return _seterror(x, Overflow);
}
Exemple #14
0
char
float_tan(
  floatnum x,
  int digits)
{
  if (!chckmathparam(x, digits))
    return 0;
  return float_getexponent(x) >= DECPRECISION - 1
         || !_trigreduce(x, digits)
         || !_tan(x, digits)? _seterror(x, EvalUnstable) : 1;
}
Exemple #15
0
char
float_arccos(
  floatnum x,
  int digits)
{
  if (!chckmathparam(x, digits))
    return 0;
  if (float_abscmp(x, &c1) > 0)
    return _seterror(x, OutOfDomain);
  _arccos(x, digits);
  return 1;
}
Exemple #16
0
char
float_cos(
  floatnum x,
  int digits)
{
  if (!chckmathparam(x, digits))
    return 0;
  if (float_getexponent(x) >= DECPRECISION - 1 || !_trigreduce(x, digits))
    return _seterror(x, EvalUnstable);
  _cos(x, digits);
  return 1;
}
Exemple #17
0
char
float_lnxplus1(
  floatnum x,
  int digits)
{
  if (!chckmathparam(x, digits))
    return 0;
  if (float_getsign(x) < 0 && float_getexponent(x) >= 0)
    return _seterror(x, OutOfDomain);
  _lnxplus1(x, digits);
  return 1;
}
Exemple #18
0
char
float_pochhammer(
  floatnum x,
  cfloatnum delta,
  int digits)
{
  if (!chckmathparam(x, digits))
    return 0;
  return float_isnan(delta)?
         _seterror(x, NoOperand)
         : _pochhammer(x, delta, digits);
}
Exemple #19
0
char
float_arccosxplus1(
  floatnum x,
  int digits)
{
  if (!chckmathparam(x, digits))
    return 0;
  if (float_getsign(x) > 0 || float_abscmp(x, &c2) > 0)
    return _seterror(x, OutOfDomain);
  _arccosxplus1(x, digits);
  return 1;
}
Exemple #20
0
char
float_arcoshxplus1(
  floatnum x,
  int digits)
{
  if (!chckmathparam(x, digits))
    return 0;
  if (float_getsign(x) < 0)
    return _seterror(x, OutOfDomain);
  _arcoshxplus1(x, digits);
  return 1;
}
Exemple #21
0
char
float_artanh(
  floatnum x,
  int digits)
{
  if (!chckmathparam(x, digits))
    return 0;
  if (float_getexponent(x) >= 0)
    return _seterror(x, OutOfDomain);
  _artanh(x, digits);
  return 1;
}
Exemple #22
0
char
float_raisei(
  floatnum power,
  cfloatnum base,
  int exponent,
  int digits)
{
  if (digits <= 0 || digits > maxdigits)
    return _seterror(power, InvalidPrecision);
  if (float_isnan(base))
    return _seterror(power, NoOperand);
  if (float_iszero(base))
  {
    if (exponent == 0)
      return _seterror(power, OutOfDomain);
    if (exponent < 0)
      return _seterror(power, ZeroDivide);
    return _setzero(power);
  }
  digits += 14;
  if (digits > maxdigits)
    digits = maxdigits;
  float_copy(power, base, digits);
  if (!_raisei(power, exponent, digits)
      || !float_isvalidexp(float_getexponent(power)))
  {
    if (float_getexponent(base) < 0)
      return _seterror(power, Underflow);
    return _seterror(power, Overflow);
  }
  return 1;
}
Error
float_in(
  floatnum x,
  p_itokens tokens)
{
  t_number_desc n;
  Error result;

  if ((result = str2desc(&n, tokens)) == Success)
    result = pack2floatnum(x, &n);
  if (result != Success)
  {
    _seterror(x, BadLiteral);
    float_setnan(x);
  }
  return result;
}
Exemple #24
0
char
float_cosh(
  floatnum x,
  int digits)
{
  int expx;

  if (!chckmathparam(x, digits))
    return 0;
  expx = float_getexponent(x);
  if (2*expx+2 <= -digits || !_coshminus1(x, digits+2*expx))
  {
    if (expx > 0)
      return _seterror(x, Overflow);
    float_setzero(x);
  }
  return float_add(x, x, &c1, digits);
}
Exemple #25
0
char
float_artanhxplus1(
  floatnum x,
  int digits)
{
  if (!chckmathparam(x, digits))
    return 0;
  if (float_getsign(x) >= 0 || float_abscmp(x, &c2) >= 0)
    return _seterror(x, OutOfDomain);
  if (float_cmp(x, &c1Div2) < 0)
  {
    float_neg(x);
    _artanh1minusx(x, digits);
  }
  else
  {
    float_sub(x, &c1, x, digits+1);
    _artanh(x, digits);
  }
  return 1;
}
Exemple #26
0
char
float_tanhminus1(
  floatnum x,
  int digits)
{
  if (!chckmathparam(x, digits))
    return 0;
  if (float_cmp(x, &c1Div2) >= 0)
    return _tanhminus1gt0(x, digits)? 1 : _seterror(x, Underflow);
  if (!float_iszero(x))
  {
    if (float_abscmp(x, &c1Div2) <= 0)
      _tanhlt0_5(x, digits);
    else
    {
      float_setsign(x, 1);
      _tanhgt0_5(x, digits);
      float_setsign(x, -1);
    }
  }
  return float_sub(x, x, &c1, digits);
}
Exemple #27
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;
}
Exemple #28
0
static char
_pochhammer_i(
  floatnum x,
  cfloatnum n,
  int digits)
{
  /* do not use the expensive Gamma function when a few
     multiplications do the same */
  /* pre: n is an integer */
  int ni;
  signed char result;

  if (float_iszero(n))
    return float_copy(x, &c1, EXACT);
  if (float_isinteger(x))
  {
    result = -1;
    float_neg((floatnum)n);
    if (float_getsign(x) <= 0 && float_cmp(x, n) > 0)
      /* x and x+n have opposite signs, meaning 0 is
         among the factors */
      result = _setzero(x);
    else if (float_getsign(x) > 0 && float_cmp(x, n) <= 0)
      /* x and x+n have opposite signs, meaning at one point
      you have to divide by 0 */
      result = _seterror(x, ZeroDivide);
    float_neg((floatnum)n);
    if (result >= 0)
      return result;
  }
  if (float_getexponent(x) < EXPMAX/100)
  {
    ni = float_asinteger(n);
    if (ni != 0 && ni < 50 && ni > -50)
      return _pochhammer_si(x, ni, digits+2);
  }
  return _pochhammer_g(x, n, digits);
}