amount_t::in_place_floor should round toward zero

This commit is contained in:
John Wiegley 2011-10-11 15:31:00 -05:00
parent d353f4fa00
commit fc67484a21

View file

@ -115,6 +115,7 @@ namespace {
mpq_t quant, mpq_t quant,
amount_t::precision_t precision, amount_t::precision_t precision,
int zeros_prec = -1, int zeros_prec = -1,
mpfr_rnd_t rnd = MPFR_RNDN,
const optional<commodity_t&>& comm = none) const optional<commodity_t&>& comm = none)
{ {
char * buf = NULL; char * buf = NULL;
@ -135,7 +136,7 @@ namespace {
DEBUG("amount.convert", "num prec = " << num_prec); DEBUG("amount.convert", "num prec = " << num_prec);
mpfr_set_prec(tempfnum, num_prec); mpfr_set_prec(tempfnum, num_prec);
mpfr_set_z(tempfnum, mpq_numref(quant), GMP_RNDN); mpfr_set_z(tempfnum, mpq_numref(quant), rnd);
mp_prec_t den_prec = mpz_sizeinbase(mpq_denref(quant), 2); mp_prec_t den_prec = mpz_sizeinbase(mpq_denref(quant), 2);
den_prec += amount_t::extend_by_digits*64; den_prec += amount_t::extend_by_digits*64;
@ -144,10 +145,10 @@ namespace {
DEBUG("amount.convert", "den prec = " << den_prec); DEBUG("amount.convert", "den prec = " << den_prec);
mpfr_set_prec(tempfden, den_prec); mpfr_set_prec(tempfden, den_prec);
mpfr_set_z(tempfden, mpq_denref(quant), GMP_RNDN); mpfr_set_z(tempfden, mpq_denref(quant), rnd);
mpfr_set_prec(tempfb, num_prec + den_prec); mpfr_set_prec(tempfb, num_prec + den_prec);
mpfr_div(tempfb, tempfnum, tempfden, GMP_RNDN); mpfr_div(tempfb, tempfnum, tempfden, rnd);
if (mpfr_asprintf(&buf, "%.*RNf", precision, tempfb) < 0) if (mpfr_asprintf(&buf, "%.*RNf", precision, tempfb) < 0)
throw_(amount_error, throw_(amount_error,
@ -669,7 +670,7 @@ void amount_t::in_place_floor()
_dup(); _dup();
std::ostringstream out; std::ostringstream out;
stream_out_mpq(out, MP(quantity), precision_t(0)); stream_out_mpq(out, MP(quantity), precision_t(0), -1, MPFR_RNDZ);
mpq_set_str(MP(quantity), out.str().c_str(), 10); mpq_set_str(MP(quantity), out.str().c_str(), 10);
} }
@ -844,8 +845,8 @@ double amount_t::to_double() const
if (! quantity) if (! quantity)
throw_(amount_error, _("Cannot convert an uninitialized amount to a double")); throw_(amount_error, _("Cannot convert an uninitialized amount to a double"));
mpfr_set_q(tempf, MP(quantity), GMP_RNDN); mpfr_set_q(tempf, MP(quantity), MPFR_RNDN);
return mpfr_get_d(tempf, GMP_RNDN); return mpfr_get_d(tempf, MPFR_RNDN);
} }
long amount_t::to_long() const long amount_t::to_long() const
@ -853,14 +854,14 @@ long amount_t::to_long() const
if (! quantity) if (! quantity)
throw_(amount_error, _("Cannot convert an uninitialized amount to a long")); throw_(amount_error, _("Cannot convert an uninitialized amount to a long"));
mpfr_set_q(tempf, MP(quantity), GMP_RNDN); mpfr_set_q(tempf, MP(quantity), MPFR_RNDN);
return mpfr_get_si(tempf, GMP_RNDN); return mpfr_get_si(tempf, MPFR_RNDN);
} }
bool amount_t::fits_in_long() const bool amount_t::fits_in_long() const
{ {
mpfr_set_q(tempf, MP(quantity), GMP_RNDN); mpfr_set_q(tempf, MP(quantity), MPFR_RNDN);
return mpfr_fits_slong_p(tempf, GMP_RNDN); return mpfr_fits_slong_p(tempf, MPFR_RNDN);
} }
commodity_t& amount_t::commodity() const commodity_t& amount_t::commodity() const
@ -1239,7 +1240,7 @@ void amount_t::print(std::ostream& _out, const uint_least8_t flags) const
} }
stream_out_mpq(out, MP(quantity), display_precision(), stream_out_mpq(out, MP(quantity), display_precision(),
comm ? commodity().precision() : 0, comm); comm ? commodity().precision() : 0, MPFR_RNDN, comm);
if (comm.has_flags(COMMODITY_STYLE_SUFFIXED)) { if (comm.has_flags(COMMODITY_STYLE_SUFFIXED)) {
if (comm.has_flags(COMMODITY_STYLE_SEPARATED)) if (comm.has_flags(COMMODITY_STYLE_SEPARATED))