Merge pull request #96 from enderw88/Bug634-floor-ceil-round
Bug 634 and 488, Corrected behavior of floor, and added ceiling
This commit is contained in:
commit
7cee6c559b
7 changed files with 78 additions and 3 deletions
|
|
@ -670,10 +670,27 @@ void amount_t::in_place_floor()
|
||||||
|
|
||||||
_dup();
|
_dup();
|
||||||
|
|
||||||
std::ostringstream out;
|
mpz_t quot;
|
||||||
stream_out_mpq(out, MP(quantity), precision_t(0), -1, GMP_RNDZ);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
mpq_set_str(MP(quantity), out.str().c_str(), 10);
|
void amount_t::in_place_ceiling()
|
||||||
|
{
|
||||||
|
if (! quantity)
|
||||||
|
throw_(amount_error, _("Cannot ceiling 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void amount_t::in_place_unround()
|
void amount_t::in_place_unround()
|
||||||
|
|
|
||||||
|
|
@ -364,6 +364,15 @@ public:
|
||||||
}
|
}
|
||||||
void in_place_floor();
|
void in_place_floor();
|
||||||
|
|
||||||
|
/** Yields an amount which has lost all of its extra precision, beyond what
|
||||||
|
the display precision of the commodity would have printed. */
|
||||||
|
amount_t ceilinged() const {
|
||||||
|
amount_t temp(*this);
|
||||||
|
temp.in_place_ceiling();
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
void in_place_ceiling();
|
||||||
|
|
||||||
/** Yields an amount whose display precision is never truncated, even
|
/** Yields an amount whose display precision is never truncated, even
|
||||||
though its commodity normally displays only rounded values. */
|
though its commodity normally displays only rounded values. */
|
||||||
amount_t unrounded() const {
|
amount_t unrounded() const {
|
||||||
|
|
|
||||||
|
|
@ -345,6 +345,17 @@ public:
|
||||||
pair.second.in_place_floor();
|
pair.second.in_place_floor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
balance_t ceilinged() const {
|
||||||
|
balance_t temp(*this);
|
||||||
|
temp.in_place_ceiling();
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
void in_place_ceiling() {
|
||||||
|
foreach (amounts_map::value_type& pair, amounts)
|
||||||
|
pair.second.in_place_ceiling();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
balance_t unrounded() const {
|
balance_t unrounded() const {
|
||||||
balance_t temp(*this);
|
balance_t temp(*this);
|
||||||
temp.in_place_unround();
|
temp.in_place_unround();
|
||||||
|
|
|
||||||
|
|
@ -681,6 +681,11 @@ value_t report_t::fn_floor(call_scope_t& args)
|
||||||
return args[0].floored();
|
return args[0].floored();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value_t report_t::fn_ceiling(call_scope_t& args)
|
||||||
|
{
|
||||||
|
return args[0].ceilinged();
|
||||||
|
}
|
||||||
|
|
||||||
value_t report_t::fn_round(call_scope_t& args)
|
value_t report_t::fn_round(call_scope_t& args)
|
||||||
{
|
{
|
||||||
return args[0].rounded();
|
return args[0].rounded();
|
||||||
|
|
@ -1335,6 +1340,8 @@ expr_t::ptr_op_t report_t::lookup(const symbol_t::kind_t kind,
|
||||||
return WRAP_FUNCTOR(fn_cyan);
|
return WRAP_FUNCTOR(fn_cyan);
|
||||||
else if (is_eq(p, "commodity"))
|
else if (is_eq(p, "commodity"))
|
||||||
return MAKE_FUNCTOR(report_t::fn_commodity);
|
return MAKE_FUNCTOR(report_t::fn_commodity);
|
||||||
|
else if (is_eq(p, "ceiling"))
|
||||||
|
return MAKE_FUNCTOR(report_t::fn_ceiling);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,7 @@ public:
|
||||||
value_t fn_unrounded(call_scope_t& scope);
|
value_t fn_unrounded(call_scope_t& scope);
|
||||||
value_t fn_truncated(call_scope_t& scope);
|
value_t fn_truncated(call_scope_t& scope);
|
||||||
value_t fn_floor(call_scope_t& scope);
|
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_round(call_scope_t& scope);
|
||||||
value_t fn_unround(call_scope_t& scope);
|
value_t fn_unround(call_scope_t& scope);
|
||||||
value_t fn_abs(call_scope_t& scope);
|
value_t fn_abs(call_scope_t& scope);
|
||||||
|
|
|
||||||
23
src/value.cc
23
src/value.cc
|
|
@ -1658,6 +1658,29 @@ void value_t::in_place_floor()
|
||||||
throw_(value_error, _f("Cannot floor %1%") % label());
|
throw_(value_error, _f("Cannot floor %1%") % label());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void value_t::in_place_ceiling()
|
||||||
|
{
|
||||||
|
switch (type()) {
|
||||||
|
case INTEGER:
|
||||||
|
return;
|
||||||
|
case AMOUNT:
|
||||||
|
as_amount_lval().in_place_ceiling();
|
||||||
|
return;
|
||||||
|
case BALANCE:
|
||||||
|
as_balance_lval().in_place_ceiling();
|
||||||
|
return;
|
||||||
|
case SEQUENCE:
|
||||||
|
foreach (value_t& value, as_sequence_lval())
|
||||||
|
value.in_place_ceiling();
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
add_error_context(_f("While ceiling %1%:") % *this);
|
||||||
|
throw_(value_error, _f("Cannot ceiling %1%") % label());
|
||||||
|
}
|
||||||
|
|
||||||
void value_t::in_place_unround()
|
void value_t::in_place_unround()
|
||||||
{
|
{
|
||||||
switch (type()) {
|
switch (type()) {
|
||||||
|
|
|
||||||
|
|
@ -457,6 +457,13 @@ public:
|
||||||
}
|
}
|
||||||
void in_place_floor();
|
void in_place_floor();
|
||||||
|
|
||||||
|
value_t ceilinged() const {
|
||||||
|
value_t temp(*this);
|
||||||
|
temp.in_place_ceiling();
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
void in_place_ceiling();
|
||||||
|
|
||||||
value_t unrounded() const {
|
value_t unrounded() const {
|
||||||
value_t temp(*this);
|
value_t temp(*this);
|
||||||
temp.in_place_unround();
|
temp.in_place_unround();
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue