Ejemplo n.º 1
0
char
_gamma0_5(
  floatnum x,
  int digits)
{
  floatstruct tmp;
  int ofs;

  if (float_getexponent(x) >= 2)
    return _gamma(x, digits);
  float_create(&tmp);
  float_sub(&tmp, x, &c1Div2, EXACT);
  ofs = float_asinteger(&tmp);
  float_free(&tmp);
  if (ofs >= 0)
  {
    float_copy(x, &c1Div2, EXACT);
    if(!_pochhammer_su(x, ofs, digits))
      return 0;
    return float_mul(x, x, &cSqrtPi, digits);
  }
  if(!_pochhammer_su(x, -ofs, digits))
    return 0;
  return float_div(x, &cSqrtPi, x, digits);
}
Ejemplo n.º 2
0
void factrat(PRAT* px, uint32_t radix, int32_t precision)

{
    PRAT fact = nullptr;
    PRAT frac = nullptr;
    PRAT neg_rat_one = nullptr;

    if (rat_gt(*px, rat_max_fact, precision) || rat_lt(*px, rat_min_fact, precision))
    {
        // Don't attempt factorial of anything too large or small.
        throw CALC_E_OVERFLOW;
    }

    DUPRAT(fact, rat_one);

    DUPRAT(neg_rat_one, rat_one);
    neg_rat_one->pp->sign *= -1;

    DUPRAT(frac, *px);
    fracrat(&frac, radix, precision);

    // Check for negative integers and throw an error.
    if ((zerrat(frac) || (LOGRATRADIX(frac) <= -precision)) && (SIGN(*px) == -1))
    {
        throw CALC_E_DOMAIN;
    }
    while (rat_gt(*px, rat_zero, precision) && (LOGRATRADIX(*px) > -precision))
    {
        mulrat(&fact, *px, precision);
        subrat(px, rat_one, precision);
    }

    // Added to make numbers 'close enough' to integers use integer factorial.
    if (LOGRATRADIX(*px) <= -precision)
    {
        DUPRAT((*px), rat_zero);
        intrat(&fact, radix, precision);
    }

    while (rat_lt(*px, neg_rat_one, precision))
    {
        addrat(px, rat_one, precision);
        divrat(&fact, *px, precision);
    }

    if (rat_neq(*px, rat_zero, precision))
    {
        addrat(px, rat_one, precision);
        _gamma(px, radix, precision);
        mulrat(px, fact, precision);
    }
    else
    {
        DUPRAT(*px, fact);
    }

    destroyrat(fact);
    destroyrat(frac);
    destroyrat(neg_rat_one);
}
Ejemplo n.º 3
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;
}
GERG2008DepartureFunction::GERG2008DepartureFunction(const std::vector<double> &n,const std::vector<double> &d,const std::vector<double> &t,
                                                     const std::vector<double> &eta,const std::vector<double> &epsilon,const std::vector<double> &beta,
                                                     const std::vector<double> &gamma, unsigned int Npower)
{

    /// Break up into power and gaussian terms
    {
        std::vector<long double> _n(n.begin(), n.begin()+Npower);
        std::vector<long double> _d(d.begin(), d.begin()+Npower);
        std::vector<long double> _t(t.begin(), t.begin()+Npower);
        std::vector<long double> _l(Npower, 0.0);
        phi.add_Power(_n, _d, _t, _l);
    }
    if (n.size() == Npower)
    {
        using_gaussian = false;
    }
    else
    {
        using_gaussian = true;
        std::vector<long double> _n(n.begin()+Npower,                   n.end());
        std::vector<long double> _d(d.begin()+Npower,                   d.end());
        std::vector<long double> _t(t.begin()+Npower,                   t.end());
        std::vector<long double> _eta(eta.begin()+Npower,             eta.end());
        std::vector<long double> _epsilon(epsilon.begin()+Npower, epsilon.end());
        std::vector<long double> _beta(beta.begin()+Npower,          beta.end());
        std::vector<long double> _gamma(gamma.begin()+Npower,       gamma.end());
        phi.add_GERG2008Gaussian(_n, _d, _t, _eta, _epsilon, _beta, _gamma);
    }
}
Ejemplo n.º 5
0
void find_post_variable_value_fluid(np_t *np, long l, gl_t *gl,
                          long varnum, double *varvalue){
  spec_t w,nu;
  double eta,kappa;


  *varvalue=0.0;
  if (is_node_valid(np[l],TYPELEVEL_FLUID)){
    if (varnum<ns) *varvalue=_w(np[l],varnum);
    if (varnum>=ns && varnum<ns+nd) *varvalue=_V(np[l],varnum-ns);
    //assert(is_node_resumed(np[l]));
    find_w(np[l],w);
    find_nuk_eta_kappa(w, _rho(np[l]), _T(np[l],gl),  nu, &eta, &kappa);
    
    switch (varnum) {
      case nd+ns+0:   *varvalue=_rho(np[l]);       break;
      case nd+ns+1:   *varvalue=_P(np[l],gl);         break;
      case nd+ns+2:   *varvalue=_Pstar(np[l],gl);     break;
      case nd+ns+3:   *varvalue=_T(np[l],gl);         break;
      case nd+ns+4:   *varvalue=_Tv(np[l]);         break;
      case nd+ns+5:   *varvalue=_a(np[l],gl);         break;
      case nd+ns+6:   *varvalue=_eta(np[l],gl);        break;
      case nd+ns+7:   *varvalue=_etastar(np,l,gl);    break;
      case nd+ns+8:   *varvalue=_kappastar(np,l,gl); break;
      case nd+ns+9:   *varvalue=_k(np[l]);         break;
      case nd+ns+10:   *varvalue=_eps(np[l],gl);       break;
      case nd+ns+11:  *varvalue=_omega(np[l],gl);     break;
      case nd+ns+12:  *varvalue=_gamma(np[l],gl);     break;
    }
  }
}