summaryrefslogtreecommitdiff
path: root/src/amount.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2010-05-26 00:58:04 -0600
committerJohn Wiegley <johnw@newartisans.com>2010-05-26 00:58:04 -0600
commit04461f49fdc0f70d74172c77843be3e0a9fe313f (patch)
tree9a6d61007fb16be8a4d372b96d75b46ef69e902c /src/amount.cc
parentdd8f4ce88f22f7ec6712738af7cac635e388fd69 (diff)
downloadfork-ledger-04461f49fdc0f70d74172c77843be3e0a9fe313f.tar.gz
fork-ledger-04461f49fdc0f70d74172c77843be3e0a9fe313f.tar.bz2
fork-ledger-04461f49fdc0f70d74172c77843be3e0a9fe313f.zip
Optimized amount_t::in_place_truncate
Diffstat (limited to 'src/amount.cc')
-rw-r--r--src/amount.cc38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/amount.cc b/src/amount.cc
index 3a64577f..a16d287e 100644
--- a/src/amount.cc
+++ b/src/amount.cc
@@ -594,6 +594,44 @@ void amount_t::in_place_round()
set_keep_precision(false);
}
+void amount_t::in_place_truncate()
+{
+#if 1
+ if (! quantity)
+ throw_(amount_error, _("Cannot truncate an uninitialized amount"));
+
+ _dup();
+
+ DEBUG("amount.truncate",
+ "Truncating " << *this << " to precision " << display_precision());
+
+ std::ostringstream out;
+ stream_out_mpq(out, MP(quantity), display_precision());
+
+ scoped_array<char> buf(new char [out.str().length() + 1]);
+ std::strcpy(buf.get(), out.str().c_str());
+
+ char * q = buf.get();
+ for (char * p = q; *p != '\0'; p++, q++) {
+ if (*p == '.') p++;
+ if (p != q) *q = *p;
+ }
+ *q = '\0';
+
+ mpq_set_str(MP(quantity), buf.get(), 10);
+
+ mpz_ui_pow_ui(temp, 10, display_precision());
+ mpq_set_z(tempq, temp);
+ mpq_div(MP(quantity), MP(quantity), tempq);
+
+ DEBUG("amount.truncate", "Truncated = " << *this);
+#else
+ // This naive implementation is straightforward, but extremely inefficient
+ // as it requires parsing the commodity too, which might be fully annotated.
+ *this = amount_t(to_string());
+#endif
+}
+
void amount_t::in_place_floor()
{
if (! quantity)