Made commodity reduction during parsing consistent

This commit is contained in:
John Wiegley 2009-02-24 02:40:28 -04:00
parent 2422838005
commit 267b2ba5d8
4 changed files with 25 additions and 21 deletions

View file

@ -501,11 +501,21 @@ void amount_t::in_place_unreduce()
if (! quantity) if (! quantity)
throw_(amount_error, "Cannot unreduce an uninitialized amount"); throw_(amount_error, "Cannot unreduce an uninitialized amount");
while (commodity_ && commodity().larger()) { amount_t temp = *this;
*this /= commodity().larger()->number(); commodity_t * comm = commodity_;
commodity_ = commodity().larger()->commodity_; bool shifted = false;
if (abs() < amount_t(1L))
while (comm && comm->larger()) {
temp /= comm->larger()->number();
if (temp.abs() < amount_t(1L))
break; break;
shifted = true;
comm = comm->larger()->commodity_;
}
if (shifted) {
*this = temp;
commodity_ = comm;
} }
} }
@ -718,7 +728,7 @@ void amount_t::annotate(const annotation_t& details)
assert(false); assert(false);
#endif #endif
DEBUG("amounts.commodities", " Annotated amount is " << *this); DEBUG("amounts.commodities", "Annotated amount is " << *this);
} }
bool amount_t::is_annotated() const bool amount_t::is_annotated() const

View file

@ -638,7 +638,8 @@ void annotation_t::parse(std::istream& in)
amount_t temp; amount_t temp;
temp.parse(buf, amount_t::PARSE_NO_MIGRATE); temp.parse(buf, amount_t::PARSE_NO_MIGRATE);
temp.in_place_reduce();
DEBUG("commodity.annotations", "Parsed annotation price: " << temp);
// Since this price will maintain its own precision, make sure // Since this price will maintain its own precision, make sure
// it is at least as large as the base commodity, since the user // it is at least as large as the base commodity, since the user
@ -683,8 +684,12 @@ void annotation_t::parse(std::istream& in)
} }
} while (true); } while (true);
#if defined(DEBUG_ON)
if (SHOW_DEBUG("amounts.commodities") && *this) {
DEBUG("amounts.commodities", DEBUG("amounts.commodities",
"Parsed commodity annotations: " << std::endl << *this); "Parsed commodity annotations: " << std::endl << *this);
}
#endif
} }
bool annotated_commodity_t::operator==(const commodity_t& comm) const bool annotated_commodity_t::operator==(const commodity_t& comm) const
@ -775,9 +780,7 @@ bool compare_amount_commodities::operator()(const amount_t * left,
if (aleftcomm.details.price && arightcomm.details.price) { if (aleftcomm.details.price && arightcomm.details.price) {
amount_t leftprice(*aleftcomm.details.price); amount_t leftprice(*aleftcomm.details.price);
leftprice.in_place_reduce();
amount_t rightprice(*arightcomm.details.price); amount_t rightprice(*arightcomm.details.price);
rightprice.in_place_reduce();
if (leftprice.commodity() == rightprice.commodity()) { if (leftprice.commodity() == rightprice.commodity()) {
return (leftprice - rightprice).sign() < 0; return (leftprice - rightprice).sign() < 0;

View file

@ -53,8 +53,7 @@ namespace {
sort_values.push_back(sort_value_t()); sort_values.push_back(sort_value_t());
sort_values.back().inverted = inverted; sort_values.back().inverted = inverted;
sort_values.back().value = sort_values.back().value = expr_t(node).calc(*scope).simplified();
expr_t(node).calc(*scope).reduced().simplified();
if (sort_values.back().value.is_null()) if (sort_values.back().value.is_null())
throw_(calc_error, throw_(calc_error,

View file

@ -828,10 +828,9 @@ post_t * instance_t::parse_post(char * line,
ptristream stream(next, len - beg); ptristream stream(next, len - beg);
if (*next != '(') // indicates a value expression if (*next != '(') // indicates a value expression
post->amount.parse(stream, amount_t::PARSE_NO_REDUCE); post->amount.parse(stream);
else else
parse_amount_expr(session_scope, stream, post->amount, post.get(), parse_amount_expr(session_scope, stream, post->amount, post.get(),
static_cast<uint_least8_t>(expr_t::PARSE_NO_REDUCE) |
static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN)); static_cast<uint_least8_t>(expr_t::PARSE_NO_ASSIGN));
if (! post->amount.is_null() && honor_strict && strict && if (! post->amount.is_null() && honor_strict && strict &&
@ -843,13 +842,6 @@ post_t * instance_t::parse_post(char * line,
<< "'" << std::endl; << "'" << std::endl;
post->amount.commodity().add_flags(COMMODITY_KNOWN); post->amount.commodity().add_flags(COMMODITY_KNOWN);
} }
#if 0
// jww (2009-02-12): This isn't quite working yet; it causes cost computes
// to skyrocket, since the per-unit price isn't also being reduced by the
// same factor.
if (! post->amount.is_null())
post->amount.in_place_reduce();
#endif
DEBUG("textual.parse", "line " << linenum << ": " DEBUG("textual.parse", "line " << linenum << ": "
<< "post amount = " << post->amount); << "post amount = " << post->amount);