Bug 634 and 488, Corrected behavior of floor, and added ceiling
This is only a partial fix for 634, since rounding is not fixed.
This commit is contained in:
parent
4b261f99bc
commit
b044a74bd3
7 changed files with 78 additions and 3 deletions
|
|
@ -670,10 +670,27 @@ void amount_t::in_place_floor()
|
|||
|
||||
_dup();
|
||||
|
||||
std::ostringstream out;
|
||||
stream_out_mpq(out, MP(quantity), precision_t(0), -1, GMP_RNDZ);
|
||||
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);
|
||||
}
|
||||
|
||||
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()
|
||||
|
|
|
|||
|
|
@ -364,6 +364,15 @@ public:
|
|||
}
|
||||
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
|
||||
though its commodity normally displays only rounded values. */
|
||||
amount_t unrounded() const {
|
||||
|
|
|
|||
|
|
@ -345,6 +345,17 @@ public:
|
|||
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 temp(*this);
|
||||
temp.in_place_unround();
|
||||
|
|
|
|||
|
|
@ -681,6 +681,11 @@ value_t report_t::fn_floor(call_scope_t& args)
|
|||
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)
|
||||
{
|
||||
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);
|
||||
else if (is_eq(p, "commodity"))
|
||||
return MAKE_FUNCTOR(report_t::fn_commodity);
|
||||
else if (is_eq(p, "ceiling"))
|
||||
return MAKE_FUNCTOR(report_t::fn_ceiling);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
|
|
|
|||
|
|
@ -174,6 +174,7 @@ public:
|
|||
value_t fn_unrounded(call_scope_t& scope);
|
||||
value_t fn_truncated(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_unround(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());
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
switch (type()) {
|
||||
|
|
|
|||
|
|
@ -457,6 +457,13 @@ public:
|
|||
}
|
||||
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 temp(*this);
|
||||
temp.in_place_unround();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue