void agm(mpf_class& rop1, mpf_class& rop2, const mpf_class& op1,
        const mpf_class& op2)
{
    rop1 = (op1 + op2) / 2;
    rop2 = op1 * op2;
    mpf_sqrt(rop2.get_mpf_t(), rop2.get_mpf_t());
}
示例#2
0
void print_mpf(mpf_class number, const unsigned int d) {
  mp_exp_t exp;
  string result = number.get_str(exp);

  // adding leading zeroes
  if (exp < 0) {
    result = string(-exp, '0').append(result);
    exp = 0;
  }
  // adding trailing zeroes
  else if (result.size() < exp) {
    result = result.append(string(exp - result.size(), '0'));
    exp = result.size();
  }

  // adding point on the front
  if (exp == 0) {
    result = string("0.").append(result);
    exp = 1;
  }
  // adding point in the middle
  else if (exp < result.size()) {
    result = result
      .substr(0, exp)
      .append(".")
      .append(result.substr(exp, result.size()));
  }

  // rounding the number
  if (result.size() - exp > d) {
    result = result.substr(0, exp + d + 1);
  }

  cout << result << endl;
}
示例#3
0
bool _Format_f(Signal &sig, Formatter *pFormatter,
					const Formatter::Flags &flags, const mpf_class &num)
{
	char *str = nullptr;
	::gmp_asprintf(&str, Formatter::ComposeFlags(flags, "Ff").c_str(), num.get_mpf_t());
	bool rtn = pFormatter->PutString(sig, str);
	::free(str);
	return rtn;
}
示例#4
0
expression_tree numeric_Power(const expression_tree::operands_t& ops, enviroment& env) {
    if ( ops.size() != 2 ) {
        env.raise_error("numeric Power", "called with invalid arguments");
        return expression_tree::make_operator( "Power", ops );       
    }

    //double powering
    mpf_class base;

    
    switch ( ops[0].get_type() ) {
    case expression_tree::EXACT_NUMBER :
        base = ops[0].get_exact_number();
        break;
    case expression_tree::APPROXIMATE_NUMBER :
        base = ops[0].get_approximate_number();
        break;
    default:
        return expression_tree::make_operator("Power", ops);
    }

    //if exp is an integral value, then use pow(double, int) version

    const bool approx_num = ops[1].get_type() == expression_tree::APPROXIMATE_NUMBER;
    const bool rational_num = ops[1].get_type() == expression_tree::EXACT_NUMBER && !is_mpq_integer(ops[1].get_exact_number());

    if (approx_num || rational_num) {
        const mpf_class exp = ops[1].get_number_as_mpf();
        if ( base < 0 || (base == 0 && exp < 0) ) {
            env.raise_error( "numeric Power", "Indeterminate expression encountered" );
            return expression_tree::make_symbol("Indeterminate");
        } else if ( base == 0 && exp < 0 ) {
            return expression_tree::make_symbol("Infinity");
        }
        return expression_tree::make_approximate_number( mpf_class(std::pow(base.get_d(), exp.get_d())) );

    } else if ( ops[1].get_type() == expression_tree::EXACT_NUMBER ) {

        long exp = 0;

        if ( !mpz_get_si_checked( exp, ops[1].get_exact_number() ) ) {
            env.raise_error("numeric Power", "exponent overflow");
            return expression_tree::make_operator("Power", ops);
        }
        if ( base == 0 && exp < 0 ) {
            return expression_tree::make_symbol("Infinity");
        }

        return expression_tree::make_approximate_number( mpf_class(std::pow(base.get_d(), exp)) );

    } else {
        return expression_tree::make_operator("Power", ops);
    }
    
}
示例#5
0
//
// The core Gauss - Legendre routine.
// On input, 'bits' is the desired precision in bits.
// On output, 'pi' contains the calculated value.
//
static void calculatePi( unsigned bits, mpf_class & pi )
{
    mpf_class lastPi( 0.0 );
    mpf_class scratch;

    // variables per the formal Gauss - Legendre formulae
    mpf_class a;
    mpf_class b;
    mpf_class t;
    mpf_class x;
    mpf_class y;
    unsigned p = 1;

    // initial conditions
    a = 1;
    // b := 1 / sqrt( 2 )
    mpf_sqrt_ui( b.get_mpf_t( ), 2 );
    b = 1.0 / b;
    t = 0.25;

    for( ;; ) {
        x = ( a + b )/2;

        // y := sqrt( ab )
        y = a * b;
        mpf_sqrt( y.get_mpf_t( ), y.get_mpf_t( ) );

        // t := t - p * ( a - x )**2
        scratch =  a - x;
        scratch *= scratch;
        scratch *= p;
        t -= scratch;

        a = x;
        b = y;
        p <<= 1;

        // pi := ( ( a + b )**2 ) / 4t
        pi = a + b;
        pi *= pi;
        pi /= ( 4 * t );

        // if pi == lastPi, within the requested precision, we're done
        if ( mpf_eq( pi.get_mpf_t( ), lastPi.get_mpf_t( ), bits ) ) {
            break;
        }
        lastPi =  pi;
    }
}
示例#6
0
std::string fixTrailingZeros(mpf_class &num, int precision) {
    char *buffer = NULL;
    gmp_asprintf(&buffer, "%.*Ff", precision + 2, num.get_mpf_t());

    int counter = strlen(buffer) - 2;

    buffer[counter] = '\0';
    --counter;

    while (buffer[counter] == '0') {
        buffer[counter] = '\0';
        --counter;
    }

    if (buffer[counter] == '.') {
        buffer[counter] = '\0';
    }

    return std::string(buffer);
}
示例#7
0
/* 
 * Evaluate the series 1/0! + 1/1! + 1/2! + 1/3! + 1/4! ...
 * On input, 'bits' is the desired precision in bits.
 * On output, e' contains the calculated value.
 */
static void calculateE(
	unsigned bits,
	mpf_class &e)
{
	/* initial conditions, including the first two terms */
	mpf_class lastE(0.0);
	mpf_class invFact(1.0);			/* 1/2!, 1/3!, 1/4!, etc. */
	unsigned term = 2;				/* 2, 3, 4... */
	e = 2;
	
	for(;;) {
		invFact /= term;
		e += invFact;
		
		/* if e == lastE, within the requested precision, we're done */
		if(mpf_eq(e.get_mpf_t(), lastE.get_mpf_t(), bits)) {
			return;
		}
		lastE = e;
		term++;
	}
	/* NOT REACHED */
}
示例#8
0
QDebug operator<<(QDebug s, const mpf_class& m) {
    char b[65536] = "";
    gmp_sprintf (b, "%.9Ff", m.get_mpf_t());
    s << b;
    return s;
}
示例#9
0
mpoint::mpoint(const mpf_class xx, const mpf_class yy, const mpf_class zz)
:x_(xx.get_d()), y_(yy.get_d()), z_(zz.get_d())
{
}
示例#10
0
mpoint::mpoint(const mpf_class xx, const mpf_class yy)
:x_(xx.get_d()), y_(yy.get_d()), z_(1)
{
}