diff options
-rw-r--r-- | src/amount.cc | 38 | ||||
-rw-r--r-- | src/amount.h | 4 | ||||
-rw-r--r-- | test/regress/25A099C9.test | 12 |
3 files changed, 45 insertions, 9 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) diff --git a/src/amount.h b/src/amount.h index 5c1bca46..ae0e5a69 100644 --- a/src/amount.h +++ b/src/amount.h @@ -346,9 +346,7 @@ public: temp.in_place_truncate(); return temp; } - void in_place_truncate() { - *this = amount_t(to_string()); - } + void in_place_truncate(); /** Yields an amount which has lost all of its extra precision, beyond what the display precision of the commodity would have printed. */ diff --git a/test/regress/25A099C9.test b/test/regress/25A099C9.test index 4067d005..a74b0601 100644 --- a/test/regress/25A099C9.test +++ b/test/regress/25A099C9.test @@ -4,16 +4,16 @@ >>>2 While parsing file "$sourcepath/src/amount.h", line 67: Error: No quantity specified for amount -While parsing file "$sourcepath/src/amount.h", line 720: +While parsing file "$sourcepath/src/amount.h", line 718: Error: Invalid date/time: line amount_t amoun -While parsing file "$sourcepath/src/amount.h", line 726: +While parsing file "$sourcepath/src/amount.h", line 724: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 732: +While parsing file "$sourcepath/src/amount.h", line 730: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 738: +While parsing file "$sourcepath/src/amount.h", line 736: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 744: +While parsing file "$sourcepath/src/amount.h", line 742: Error: Invalid date/time: line std::ostream& -While parsing file "$sourcepath/src/amount.h", line 751: +While parsing file "$sourcepath/src/amount.h", line 749: Error: Invalid date/time: line std::istream& === 7 |