summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2008-09-14 19:36:55 -0400
committerJohn Wiegley <johnw@newartisans.com>2008-09-14 19:36:55 -0400
commit0135c28049839c2db25351b8d8114f9f31649afc (patch)
tree6a7871175a462eacd92468b77fced92714169f0b
parent3add2229e0dd1f583596a313a76991249a521bae (diff)
downloadfork-ledger-0135c28049839c2db25351b8d8114f9f31649afc.tar.gz
fork-ledger-0135c28049839c2db25351b8d8114f9f31649afc.tar.bz2
fork-ledger-0135c28049839c2db25351b8d8114f9f31649afc.zip
Added in_place_round method to all Ledger numerical types.
-rw-r--r--src/amount.cc34
-rw-r--r--src/amount.h16
-rw-r--r--src/balance.h12
-rw-r--r--src/value.cc20
-rw-r--r--src/value.h1
5 files changed, 64 insertions, 19 deletions
diff --git a/src/amount.cc b/src/amount.cc
index d3265bc0..8d433ad4 100644
--- a/src/amount.cc
+++ b/src/amount.cc
@@ -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
diff --git a/src/amount.h b/src/amount.h
index 0c849017..006c554a 100644
--- a/src/amount.h
+++ b/src/amount.h
@@ -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 {
diff --git a/src/balance.h b/src/balance.h
index fcf4fe36..d00fadb1 100644
--- a/src/balance.h
+++ b/src/balance.h
@@ -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)
diff --git a/src/value.cc b/src/value.cc
index b079c54b..be78327a 100644
--- a/src/value.cc
+++ b/src/value.cc
@@ -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()) {
diff --git a/src/value.h b/src/value.h
index 7a021386..83a9976e 100644
--- a/src/value.h
+++ b/src/value.h
@@ -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 {