Пример #1
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;
}
Пример #2
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;
}
Пример #3
0
void
_cos(
  floatnum x,
  int digits)
{
  signed char sgn;

  float_abs(x);
  sgn = 1;
  if (float_cmp(x, &cPiDiv2) > 0)
  {
    sgn = -1;
    float_sub(x, &cPi, x, digits+1);
  }
  if (float_cmp(x, &cPiDiv4) <= 0)
  {
    if (2*float_getexponent(x)+2 < - digits)
      float_setzero(x);
    else
      _cosminus1ltPiDiv4(x, digits);
    float_add(x, x, &c1, digits);
  }
  else
  {
    float_sub(x, &cPiDiv2, x, digits+1);
    _sinltPiDiv4(x, digits);
  }
  float_setsign(x, sgn);
}
Пример #4
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);
}
Пример #5
0
/**
 * Uses float_cmp to compare an array element-by-element using a specified tolerance.
 * Returns a number less than, equal to, or greater than zero.
 */
int float_cmp_array(float *a, float *b, float tol, size_t nelem) {
    for(size_t i = 0; i < nelem; i++) {
        int res = float_cmp(a[i], b[i], tol);
        if(res != 0)
            return res;
    }
    return 0;
}
Пример #6
0
/* evaluates cos x - 1 for |x| <= pi.
   This function may underflow, which
   is indicated by the return value 0 */
char
_cosminus1(
  floatnum x,
  int digits)
{
  float_abs(x);
  if (float_cmp(x, &cPiDiv4) <= 0)
    return _cosminus1ltPiDiv4(x, digits);
  _cos(x, digits);
  float_sub(x, x, &c1, digits);
  return 1;
}
Пример #7
0
int test_131() {
    size_t m = 1;
    size_t n = 3;
    size_t p = 1;

    float a[3] = {1, 2, 3};
    float b[3] = {1, 2, 3};
    float c[1];

    matrix_multiply(a, b, c, m, n, p);
    ASSERT(!float_cmp(c[0], 14.0f, TOLERANCE));
    return 1;
}
Пример #8
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);
}
Пример #9
0
char
float_tanh(
  floatnum x,
  int digits)
{
  signed char sgn;

  if (!chckmathparam(x, digits))
    return 0;
  sgn = float_getsign(x);
  float_abs(x);
  if (float_cmp(x, &c1Div2) >= 0)
    _tanhgt0_5(x, digits);
  else
    _tanhlt0_5(x, digits);
  float_setsign(x, sgn);
  return 1;
}
Пример #10
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;
}
Пример #11
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);
}
Пример #12
0
/* evaluates arccos x for -1 <= x <= 1.
   The result is in the range 0 <= result <= pi.
   The relative error for a 100 digit result is < 5e-100 */
void
_arccos(
  floatnum x,
  int digits)
{
  signed char sgn;

  sgn = float_getsign(x);
  float_abs(x);
  if (float_cmp(x, &c1Div2) > 0)
  {
    float_sub(x, x, &c1, digits+1);
    _arccosxplus1lt0_5(x, digits);
  }
  else
  {
    _arcsinlt0_5(x, digits);
    float_sub(x, &cPiDiv2, x, digits+1);
  }
  if (sgn < 0)
    float_sub(x, &cPi, x, digits+1);
}
Пример #13
0
void TemplateTable::double_cmp(int unordered_result) {
  transition(dtos, itos);
  float_cmp(false, unordered_result);
}
Пример #14
0
void TemplateTable::float_cmp(int unordered_result) {
  transition(ftos, itos);
  float_cmp(true, unordered_result);
}