diff options
-rw-r--r-- | doc/ledger3.texi | 4 | ||||
-rw-r--r-- | src/amount.cc | 29 | ||||
-rw-r--r-- | src/amount.h | 7 | ||||
-rw-r--r-- | src/balance.h | 11 | ||||
-rw-r--r-- | src/report.cc | 8 | ||||
-rw-r--r-- | src/report.h | 1 | ||||
-rw-r--r-- | src/value.cc | 21 | ||||
-rw-r--r-- | src/value.h | 7 | ||||
-rw-r--r-- | test/regress/25A099C9.test | 20 |
9 files changed, 83 insertions, 25 deletions
diff --git a/doc/ledger3.texi b/doc/ledger3.texi index 377d740c..ee4c990b 100644 --- a/doc/ledger3.texi +++ b/doc/ledger3.texi @@ -7192,6 +7192,7 @@ Useful specifying a date in plain terms. For example, you could say @item @strong{Function} @tab @strong{Abbrev.} @tab @strong{Description} @item @code{amount_expr } @tab @code{} @tab @item @code{abs } @tab @code{} @tab --> U +@item @code{ceiling } @tab @code{} @tab Returns the next integer toward +infty @item @code{code} @tab @code{} @tab returns the transaction code, the string between the parenthesis after the date. @item @code{commodity } @tab @code{} @tab @item @code{display_amount } @tab @code{} @tab --> t @@ -7199,7 +7200,7 @@ Useful specifying a date in plain terms. For example, you could say @item @code{date } @tab @code{} @tab @item @code{format_date } @tab @code{} @tab @item @code{format } @tab @code{} @tab -@item @code{floor } @tab @code{} @tab +@item @code{floor } @tab @code{} @tab Returns the next integer toward -infty @item @code{get_at } @tab @code{} @tab @item @code{is_seq } @tab @code{} @tab @item @code{justify } @tab @code{} @tab @@ -7215,6 +7216,7 @@ Useful specifying a date in plain terms. For example, you could say @item @code{quoted } @tab @code{} @tab @item @code{quantity } @tab @code{} @tab @item @code{rounded } @tab @code{} @tab +@item @code{roundto } @tab @code{} @tab Returns value rounded to n digits. Does not affect formatting. @item @code{scrub } @tab @code{} @tab @item @code{strip --> S } @tab @code{} @tab @item @code{should_bold } @tab @code{} @tab diff --git a/src/amount.cc b/src/amount.cc index ee03827e..51e69290 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -30,6 +30,7 @@ */ #include <system.hh> +#include <math.h> #include "amount.h" #include "commodity.h" @@ -672,31 +673,31 @@ void amount_t::in_place_truncate() void amount_t::in_place_floor() { if (! quantity) - throw_(amount_error, _("Cannot floor an uninitialized amount")); + throw_(amount_error, _("Cannot compute floor on an uninitialized amount")); _dup(); - mpz_t quot; - mpz_init(quot); - mpz_fdiv_q(quot, mpq_numref(MP(quantity)), mpq_denref(MP(quantity))); - mpq_clear(MP(quantity)); - mpq_init(MP(quantity)); - mpq_set_num(MP(quantity), quot); + mpz_fdiv_q(temp, mpq_numref(MP(quantity)), mpq_denref(MP(quantity))); + mpq_set_z(MP(quantity), temp); } void amount_t::in_place_ceiling() { if (! quantity) - throw_(amount_error, _("Cannot ceiling an uninitialized amount")); + throw_(amount_error, _("Cannot compute ceiling on an uninitialized amount")); _dup(); - mpz_t quot; - mpz_init(quot); - mpz_cdiv_q(quot, mpq_numref(MP(quantity)), mpq_denref(MP(quantity))); - mpq_clear(MP(quantity)); - mpq_init(MP(quantity)); - mpq_set_num(MP(quantity), quot); + mpz_cdiv_q(temp, mpq_numref(MP(quantity)), mpq_denref(MP(quantity))); + mpq_set_z(MP(quantity), temp); +} + +void amount_t::in_place_roundto(int places) +{ + if (! quantity) + throw_(amount_error, _("Cannot round an uninitialized amount")); + double x=ceil(mpq_get_d(MP(quantity))*pow(10, places) - 0.49999999) / pow(10, places); + mpq_set_d(MP(quantity), x); } void amount_t::in_place_unround() diff --git a/src/amount.h b/src/amount.h index 1b7d2101..5fc2ad2e 100644 --- a/src/amount.h +++ b/src/amount.h @@ -346,6 +346,13 @@ public: } void in_place_round(); + amount_t roundto(int places) const { + amount_t temp(*this); + temp.in_place_round(); + return temp; + } + void in_place_roundto(int places); + /** Yields an amount which has lost all of its extra precision, beyond what the display precision of the commodity would have printed. */ amount_t truncated() const { diff --git a/src/balance.h b/src/balance.h index 9635742d..f822e353 100644 --- a/src/balance.h +++ b/src/balance.h @@ -325,6 +325,17 @@ public: pair.second.in_place_round(); } + balance_t roundto(int places) const { + balance_t temp(*this); + temp.in_place_roundto(places); + return temp; + } + + void in_place_roundto(int places) { + foreach (amounts_map::value_type& pair, amounts) + pair.second.in_place_roundto(places); + } + balance_t truncated() const { balance_t temp(*this); temp.in_place_truncate(); diff --git a/src/report.cc b/src/report.cc index 80993515..d90d22e4 100644 --- a/src/report.cc +++ b/src/report.cc @@ -691,6 +691,12 @@ value_t report_t::fn_round(call_scope_t& args) return args[0].rounded(); } +value_t report_t::fn_roundto(call_scope_t& args) +{ + if(args.has<int>(1)) + return args[0].roundto(args.get<int>(1)); +} + value_t report_t::fn_unround(call_scope_t& args) { return args[0].unrounded(); @@ -1435,6 +1441,8 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind, return WRAP_FUNCTOR(fn_red); else if (is_eq(p, "round")) return MAKE_FUNCTOR(report_t::fn_round); + else if (is_eq(p, "roundto")) + return MAKE_FUNCTOR(report_t::fn_roundto); break; case 's': diff --git a/src/report.h b/src/report.h index b0044f60..6533d2f1 100644 --- a/src/report.h +++ b/src/report.h @@ -176,6 +176,7 @@ public: value_t fn_floor(call_scope_t& scope); value_t fn_ceiling(call_scope_t& scope); value_t fn_round(call_scope_t& scope); + value_t fn_roundto(call_scope_t& scope); value_t fn_unround(call_scope_t& scope); value_t fn_abs(call_scope_t& scope); value_t fn_justify(call_scope_t& scope); diff --git a/src/value.cc b/src/value.cc index c57cff78..3df8f3c7 100644 --- a/src/value.cc +++ b/src/value.cc @@ -1612,6 +1612,27 @@ void value_t::in_place_round() throw_(value_error, _f("Cannot set rounding for %1%") % label()); } +void value_t::in_place_roundto(int places) +{ + DEBUG("amount.roundto", "=====> roundto places " << places); + switch (type()) { + case INTEGER: + return; + case AMOUNT: + as_amount_lval().in_place_roundto(places); + return; + case BALANCE: + as_balance_lval().in_place_roundto(places); + return; + case SEQUENCE: + foreach (value_t& value, as_sequence_lval()) + value.in_place_roundto(places); + return; + default: + break; + } +} + void value_t::in_place_truncate() { switch (type()) { diff --git a/src/value.h b/src/value.h index 249f3d7f..49d64ab6 100644 --- a/src/value.h +++ b/src/value.h @@ -443,6 +443,13 @@ public: } void in_place_round(); + value_t roundto(int places) const { + value_t temp(*this); + temp.in_place_roundto(places); + return temp; + } + void in_place_roundto(int places); + value_t truncated() const { value_t temp(*this); temp.in_place_truncate(); diff --git a/test/regress/25A099C9.test b/test/regress/25A099C9.test index fb362a4b..34c92c40 100644 --- a/test/regress/25A099C9.test +++ b/test/regress/25A099C9.test @@ -20,24 +20,24 @@ While parsing file "$sourcepath/src/amount.h", line 121: Error: Unexpected whitespace at beginning of line While parsing file "$sourcepath/src/amount.h", line 132: Error: Unexpected whitespace at beginning of line -While parsing file "$sourcepath/src/amount.h", line 711: +While parsing file "$sourcepath/src/amount.h", line 718: Error: Unexpected whitespace at beginning of line -While parsing file "$sourcepath/src/amount.h", line 741: +While parsing file "$sourcepath/src/amount.h", line 748: Error: Unexpected whitespace at beginning of line -While parsing file "$sourcepath/src/amount.h", line 749: +While parsing file "$sourcepath/src/amount.h", line 756: Error: Unexpected whitespace at beginning of line -While parsing file "$sourcepath/src/amount.h", line 752: +While parsing file "$sourcepath/src/amount.h", line 759: Error: Invalid date/time: line amount_t amoun -While parsing file "$sourcepath/src/amount.h", line 758: +While parsing file "$sourcepath/src/amount.h", line 765: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 764: +While parsing file "$sourcepath/src/amount.h", line 771: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 770: +While parsing file "$sourcepath/src/amount.h", line 777: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 776: -Error: Invalid date/time: line std::ostream& While parsing file "$sourcepath/src/amount.h", line 783: +Error: Invalid date/time: line std::ostream& +While parsing file "$sourcepath/src/amount.h", line 790: Error: Invalid date/time: line std::istream& -While parsing file "$sourcepath/src/amount.h", line 789: +While parsing file "$sourcepath/src/amount.h", line 796: Error: Unexpected whitespace at beginning of line end test |