Merge pull request #140 from enderw88/Bug634-floor-ceil-round
Bug 634 Added roundto function, optimized floor and ceiling
This commit is contained in:
commit
d9b1258c34
9 changed files with 83 additions and 25 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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':
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
21
src/value.cc
21
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()) {
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue