Merge pull request #140 from enderw88/Bug634-floor-ceil-round

Bug 634 Added roundto function, optimized floor and ceiling
This commit is contained in:
Craig Earls 2013-01-30 18:56:00 -08:00
commit d9b1258c34
9 changed files with 83 additions and 25 deletions

View file

@ -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

View file

@ -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()

View file

@ -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 {

View file

@ -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();

View file

@ -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':

View file

@ -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);

View file

@ -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()) {

View file

@ -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();

View file

@ -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