Added in_place_round method to all Ledger numerical types.

This commit is contained in:
John Wiegley 2008-09-14 19:36:55 -04:00
parent 3add2229e0
commit 0135c28049
5 changed files with 64 additions and 19 deletions

View file

@ -571,40 +571,40 @@ amount_t& amount_t::in_place_negate()
return *this;
}
amount_t amount_t::round() const
amount_t& amount_t::in_place_round()
{
if (! quantity)
throw_(amount_error, "Cannot round an uninitialized amount");
if (! has_commodity())
return *this;
if (has_commodity())
in_place_round(commodity().precision());
return round(commodity().precision());
return *this;
}
amount_t amount_t::round(precision_t prec) const
amount_t& amount_t::in_place_round(precision_t prec)
{
if (! quantity)
throw_(amount_error, "Cannot round an uninitialized amount");
amount_t t(*this);
if (quantity->prec <= prec) {
if (quantity && quantity->has_flags(BIGINT_KEEP_PREC)) {
t._dup();
t.quantity->drop_flags(BIGINT_KEEP_PREC);
if (quantity && quantity->prec <= prec) {
if (quantity->has_flags(BIGINT_KEEP_PREC)) {
_dup();
quantity->drop_flags(BIGINT_KEEP_PREC);
}
return t;
return *this;
}
t._dup();
DEBUG("amount.round", "Rounding " << *this << " to precision " << prec);
mpz_round(MPZ(t.quantity), MPZ(t.quantity), t.quantity->prec, prec);
mpz_round(MPZ(quantity), MPZ(quantity), quantity->prec, prec);
t.quantity->prec = prec;
t.quantity->drop_flags(BIGINT_KEEP_PREC);
quantity->prec = prec;
quantity->drop_flags(BIGINT_KEEP_PREC);
return t;
DEBUG("amount.round", " result = " << *this);
return *this;
}
amount_t amount_t::unround() const

View file

@ -377,8 +377,20 @@ public:
return *this;
}
amount_t round() const;
amount_t round(precision_t prec) const;
amount_t round() const {
amount_t temp(*this);
temp.in_place_round();
return temp;
}
amount_t& in_place_round();
amount_t round(precision_t prec) const {
amount_t temp(*this);
temp.in_place_round(prec);
return temp;
}
amount_t& in_place_round(precision_t prec);
amount_t unround() const;
amount_t reduce() const {

View file

@ -324,12 +324,24 @@ public:
temp += pair.second.round();
return temp;
}
balance_t& in_place_round() {
foreach (amounts_map::value_type& pair, amounts)
pair.second.in_place_round();
return *this;
}
balance_t round(amount_t::precision_t prec) const {
balance_t temp;
foreach (const amounts_map::value_type& pair, amounts)
temp += pair.second.round(prec);
return temp;
}
balance_t& in_place_round(amount_t::precision_t prec) {
foreach (amounts_map::value_type& pair, amounts)
pair.second.in_place_round(prec);
return *this;
}
balance_t unround() const {
balance_t temp;
foreach (const amounts_map::value_type& pair, amounts)

View file

@ -1395,6 +1395,26 @@ value_t value_t::round() const
return NULL_VALUE;
}
void value_t::in_place_round()
{
switch (type()) {
case INTEGER:
break;
case AMOUNT:
as_amount_lval().in_place_round();
break;
case BALANCE:
as_balance_lval().in_place_round();
break;
case BALANCE_PAIR:
as_balance_pair_lval().in_place_round();
break;
default:
throw_(value_error, "Cannot round " << label());
break;
}
}
value_t value_t::unround() const
{
switch (type()) {

View file

@ -407,6 +407,7 @@ public:
value_t abs() const;
value_t round() const;
void in_place_round();
value_t unround() const;
value_t reduce() const {