It is now an error to use an uninitialized amount for any operation
other than is_null and parse.
This commit is contained in:
parent
0477dd119a
commit
4e9056b6ce
4 changed files with 152 additions and 176 deletions
173
src/amount.cc
173
src/amount.cc
|
|
@ -133,6 +133,8 @@ void amount_t::shutdown()
|
|||
|
||||
void amount_t::_init()
|
||||
{
|
||||
// This is only called on an initialized amount by amount_t::parse.
|
||||
|
||||
if (! quantity) {
|
||||
quantity = new bigint_t;
|
||||
}
|
||||
|
|
@ -140,6 +142,7 @@ void amount_t::_init()
|
|||
_release();
|
||||
quantity = new bigint_t;
|
||||
}
|
||||
commodity_ = NULL;
|
||||
}
|
||||
|
||||
void amount_t::_copy(const amount_t& amt)
|
||||
|
|
@ -301,28 +304,25 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
amount_t::amount_t(const double val)
|
||||
amount_t::amount_t(const double val) : commodity_(NULL)
|
||||
{
|
||||
TRACE_CTOR(amount_t, "const double");
|
||||
quantity = new bigint_t;
|
||||
quantity->prec = convert_double(MPZ(quantity), val);
|
||||
commodity_ = NULL;
|
||||
}
|
||||
|
||||
amount_t::amount_t(const unsigned long val)
|
||||
amount_t::amount_t(const unsigned long val) : commodity_(NULL)
|
||||
{
|
||||
TRACE_CTOR(amount_t, "const unsigned long");
|
||||
quantity = new bigint_t;
|
||||
mpz_set_ui(MPZ(quantity), val);
|
||||
commodity_ = NULL;
|
||||
}
|
||||
|
||||
amount_t::amount_t(const long val)
|
||||
amount_t::amount_t(const long val) : commodity_(NULL)
|
||||
{
|
||||
TRACE_CTOR(amount_t, "const long");
|
||||
quantity = new bigint_t;
|
||||
mpz_set_si(MPZ(quantity), val);
|
||||
commodity_ = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -340,15 +340,17 @@ amount_t& amount_t::operator=(const amount_t& amt)
|
|||
|
||||
int amount_t::compare(const amount_t& amt) const
|
||||
{
|
||||
if (! quantity) {
|
||||
if (! amt.quantity)
|
||||
return 0;
|
||||
return - amt.sign();
|
||||
if (! quantity || ! amt.quantity) {
|
||||
if (quantity)
|
||||
throw_(amount_error, "Cannot compare an amount to an uninitialized amount");
|
||||
else if (amt.quantity)
|
||||
throw_(amount_error, "Cannot compare an uninitialized amount to an amount");
|
||||
else
|
||||
throw_(amount_error, "Cannot compare two uninitialized amounts");
|
||||
}
|
||||
if (! amt.quantity)
|
||||
return sign();
|
||||
|
||||
if (has_commodity() && amt.commodity() && commodity() != amt.commodity())
|
||||
|
||||
if (has_commodity() && amt.has_commodity() &&
|
||||
commodity() != amt.commodity())
|
||||
throw_(amount_error,
|
||||
"Cannot compare amounts with different commodities: " <<
|
||||
commodity().symbol() << " and " << amt.commodity().symbol());
|
||||
|
|
@ -371,6 +373,15 @@ int amount_t::compare(const amount_t& amt) const
|
|||
|
||||
amount_t& amount_t::operator+=(const amount_t& amt)
|
||||
{
|
||||
if (! quantity || ! amt.quantity) {
|
||||
if (quantity)
|
||||
throw_(amount_error, "Cannot add an amount to an uninitialized amount");
|
||||
else if (amt.quantity)
|
||||
throw_(amount_error, "Cannot add an uninitialized amount to an amount");
|
||||
else
|
||||
throw_(amount_error, "Cannot add two uninitialized amounts");
|
||||
}
|
||||
|
||||
if (commodity() != amt.commodity())
|
||||
throw_(amount_error,
|
||||
"Adding amounts with different commodities: " <<
|
||||
|
|
@ -378,14 +389,6 @@ amount_t& amount_t::operator+=(const amount_t& amt)
|
|||
" != " <<
|
||||
(amt.has_commodity() ? amt.commodity().symbol() : "NONE"));
|
||||
|
||||
if (! amt.quantity)
|
||||
return *this;
|
||||
|
||||
if (! quantity) {
|
||||
_copy(amt);
|
||||
return *this;
|
||||
}
|
||||
|
||||
_dup();
|
||||
|
||||
if (quantity->prec == amt.quantity->prec) {
|
||||
|
|
@ -406,6 +409,15 @@ amount_t& amount_t::operator+=(const amount_t& amt)
|
|||
|
||||
amount_t& amount_t::operator-=(const amount_t& amt)
|
||||
{
|
||||
if (! quantity || ! amt.quantity) {
|
||||
if (quantity)
|
||||
throw_(amount_error, "Cannot subtract an amount from an uninitialized amount");
|
||||
else if (amt.quantity)
|
||||
throw_(amount_error, "Cannot subtract an uninitialized amount from an amount");
|
||||
else
|
||||
throw_(amount_error, "Cannot subtract two uninitialized amounts");
|
||||
}
|
||||
|
||||
if (commodity() != amt.commodity())
|
||||
throw_(amount_error,
|
||||
"Subtracting amounts with different commodities: " <<
|
||||
|
|
@ -413,16 +425,6 @@ amount_t& amount_t::operator-=(const amount_t& amt)
|
|||
" != " <<
|
||||
(amt.has_commodity() ? amt.commodity().symbol() : "NONE"));
|
||||
|
||||
if (! amt.quantity)
|
||||
return *this;
|
||||
|
||||
if (! quantity) {
|
||||
quantity = new bigint_t(*amt.quantity);
|
||||
commodity_ = amt.commodity_;
|
||||
mpz_neg(MPZ(quantity), MPZ(quantity));
|
||||
return *this;
|
||||
}
|
||||
|
||||
_dup();
|
||||
|
||||
if (quantity->prec == amt.quantity->prec) {
|
||||
|
|
@ -491,6 +493,15 @@ namespace {
|
|||
|
||||
amount_t& amount_t::operator*=(const amount_t& amt)
|
||||
{
|
||||
if (! quantity || ! amt.quantity) {
|
||||
if (quantity)
|
||||
throw_(amount_error, "Cannot multiply an amount by an uninitialized amount");
|
||||
else if (amt.quantity)
|
||||
throw_(amount_error, "Cannot multiply an uninitialized amount by an amount");
|
||||
else
|
||||
throw_(amount_error, "Cannot multiply two uninitialized amounts");
|
||||
}
|
||||
|
||||
if (has_commodity() && amt.has_commodity() &&
|
||||
commodity() != amt.commodity())
|
||||
throw_(amount_error,
|
||||
|
|
@ -499,16 +510,6 @@ amount_t& amount_t::operator*=(const amount_t& amt)
|
|||
" != " <<
|
||||
(amt.has_commodity() ? amt.commodity().symbol() : "NONE"));
|
||||
|
||||
if (! amt.quantity) {
|
||||
*this = *this - *this; // preserve our commodity
|
||||
goto finish;
|
||||
}
|
||||
else if (! quantity) {
|
||||
*this = amt;
|
||||
*this = *this - *this; // preserve the foreign commodity
|
||||
goto finish;
|
||||
}
|
||||
|
||||
_dup();
|
||||
|
||||
mpz_mul(MPZ(quantity), MPZ(quantity), MPZ(amt.quantity));
|
||||
|
|
@ -531,6 +532,15 @@ amount_t& amount_t::operator*=(const amount_t& amt)
|
|||
|
||||
amount_t& amount_t::operator/=(const amount_t& amt)
|
||||
{
|
||||
if (! quantity || ! amt.quantity) {
|
||||
if (quantity)
|
||||
throw_(amount_error, "Cannot divide an amount by an uninitialized amount");
|
||||
else if (amt.quantity)
|
||||
throw_(amount_error, "Cannot divide an uninitialized amount by an amount");
|
||||
else
|
||||
throw_(amount_error, "Cannot divide two uninitialized amounts");
|
||||
}
|
||||
|
||||
if (has_commodity() && amt.has_commodity() &&
|
||||
commodity() != amt.commodity())
|
||||
throw_(amount_error,
|
||||
|
|
@ -539,14 +549,8 @@ amount_t& amount_t::operator/=(const amount_t& amt)
|
|||
" != " <<
|
||||
(amt.has_commodity() ? amt.commodity().symbol() : "NONE"));
|
||||
|
||||
if (! amt.quantity || ! amt) {
|
||||
if (! amt)
|
||||
throw_(amount_error, "Divide by zero");
|
||||
}
|
||||
else if (! quantity) {
|
||||
*this = amt;
|
||||
*this = *this - *this; // preserve the foreign commodity
|
||||
goto finish;
|
||||
}
|
||||
|
||||
_dup();
|
||||
|
||||
|
|
@ -584,6 +588,9 @@ amount_t& amount_t::operator/=(const amount_t& amt)
|
|||
|
||||
amount_t::precision_t amount_t::precision() const
|
||||
{
|
||||
if (! quantity)
|
||||
throw_(amount_error, "Cannot determine precision of an uninitialized amount");
|
||||
|
||||
return quantity->prec;
|
||||
}
|
||||
|
||||
|
|
@ -592,6 +599,8 @@ amount_t& amount_t::in_place_negate()
|
|||
if (quantity) {
|
||||
_dup();
|
||||
mpz_neg(MPZ(quantity), MPZ(quantity));
|
||||
} else {
|
||||
throw_(amount_error, "Cannot negate an uninitialized amount");
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -600,7 +609,10 @@ amount_t amount_t::round(precision_t prec) const
|
|||
{
|
||||
amount_t t = *this;
|
||||
|
||||
if (! quantity || quantity->prec <= prec) {
|
||||
if (! quantity)
|
||||
throw_(amount_error, "Cannot round an uninitialized amount");
|
||||
|
||||
if (quantity->prec <= prec) {
|
||||
if (quantity && quantity->has_flags(BIGINT_KEEP_PREC)) {
|
||||
t._dup();
|
||||
t.quantity->drop_flags(BIGINT_KEEP_PREC);
|
||||
|
|
@ -620,15 +632,10 @@ amount_t amount_t::round(precision_t prec) const
|
|||
|
||||
amount_t amount_t::unround() const
|
||||
{
|
||||
if (! quantity) {
|
||||
amount_t t(0L);
|
||||
assert(t.quantity);
|
||||
t.quantity->add_flags(BIGINT_KEEP_PREC);
|
||||
return t;
|
||||
}
|
||||
else if (quantity->has_flags(BIGINT_KEEP_PREC)) {
|
||||
if (! quantity)
|
||||
throw_(amount_error, "Cannot unround an uninitialized amount");
|
||||
else if (quantity->has_flags(BIGINT_KEEP_PREC))
|
||||
return *this;
|
||||
}
|
||||
|
||||
amount_t t = *this;
|
||||
t._dup();
|
||||
|
|
@ -639,6 +646,9 @@ amount_t amount_t::unround() const
|
|||
|
||||
amount_t& amount_t::in_place_reduce()
|
||||
{
|
||||
if (! quantity)
|
||||
throw_(amount_error, "Cannot reduce an uninitialized amount");
|
||||
|
||||
while (commodity_ && commodity().smaller()) {
|
||||
*this *= commodity().smaller()->number();
|
||||
commodity_ = commodity().smaller()->commodity_;
|
||||
|
|
@ -648,6 +658,9 @@ amount_t& amount_t::in_place_reduce()
|
|||
|
||||
amount_t& amount_t::in_place_unreduce()
|
||||
{
|
||||
if (! quantity)
|
||||
throw_(amount_error, "Cannot unreduce an uninitialized amount");
|
||||
|
||||
while (commodity_ && commodity().larger()) {
|
||||
*this /= commodity().larger()->number();
|
||||
commodity_ = commodity().larger()->commodity_;
|
||||
|
|
@ -663,6 +676,8 @@ optional<amount_t> amount_t::value(const optional<moment_t>& moment) const
|
|||
optional<amount_t> amt(commodity().value(moment));
|
||||
if (amt)
|
||||
return (*amt * number()).round();
|
||||
} else {
|
||||
throw_(amount_error, "Cannot determine value of an uninitialized amount");
|
||||
}
|
||||
return optional<amount_t>();
|
||||
}
|
||||
|
|
@ -670,13 +685,16 @@ optional<amount_t> amount_t::value(const optional<moment_t>& moment) const
|
|||
|
||||
int amount_t::sign() const
|
||||
{
|
||||
return quantity ? mpz_sgn(MPZ(quantity)) : 0;
|
||||
if (! quantity)
|
||||
throw_(amount_error, "Cannot determine sign of an uninitialized amount");
|
||||
|
||||
return mpz_sgn(MPZ(quantity));
|
||||
}
|
||||
|
||||
bool amount_t::is_zero() const
|
||||
{
|
||||
if (! quantity)
|
||||
return true;
|
||||
throw_(amount_error, "Cannot determine sign if an uninitialized amount is zero");
|
||||
|
||||
if (has_commodity()) {
|
||||
if (quantity->prec <= commodity().precision())
|
||||
|
|
@ -691,7 +709,7 @@ bool amount_t::is_zero() const
|
|||
double amount_t::to_double(bool no_check) const
|
||||
{
|
||||
if (! quantity)
|
||||
return 0.0;
|
||||
throw_(amount_error, "Cannot convert an uninitialized amount to a double");
|
||||
|
||||
mpz_t remainder;
|
||||
mpz_init(remainder);
|
||||
|
|
@ -722,7 +740,7 @@ double amount_t::to_double(bool no_check) const
|
|||
long amount_t::to_long(bool no_check) const
|
||||
{
|
||||
if (! quantity)
|
||||
return 0;
|
||||
throw_(amount_error, "Cannot convert an uninitialized amount to a long");
|
||||
|
||||
mpz_set(temp, MPZ(quantity));
|
||||
mpz_ui_pow_ui(divisor, 10, quantity->prec);
|
||||
|
|
@ -754,6 +772,11 @@ void amount_t::annotate_commodity(const annotation_t& details)
|
|||
commodity_t * this_base;
|
||||
annotated_commodity_t * this_ann = NULL;
|
||||
|
||||
if (! quantity)
|
||||
throw_(amount_error, "Cannot annotate the commodity of an uninitialized amount");
|
||||
else if (! has_commodity())
|
||||
throw_(amount_error, "Cannot annotate an amount with no commodity");
|
||||
|
||||
if (commodity().annotated) {
|
||||
this_ann = &commodity().as_annotated();
|
||||
this_base = &this_ann->referent();
|
||||
|
|
@ -780,6 +803,10 @@ amount_t amount_t::strip_annotations(const bool _keep_price,
|
|||
const bool _keep_date,
|
||||
const bool _keep_tag) const
|
||||
{
|
||||
if (! quantity)
|
||||
throw_(amount_error,
|
||||
"Cannot strip commodity annotations from an uninitialized amount");
|
||||
|
||||
if (! commodity().annotated ||
|
||||
(_keep_price && _keep_date && _keep_tag))
|
||||
return *this;
|
||||
|
|
@ -817,12 +844,20 @@ amount_t amount_t::strip_annotations(const bool _keep_price,
|
|||
|
||||
bool amount_t::commodity_annotated() const
|
||||
{
|
||||
if (! quantity)
|
||||
throw_(amount_error,
|
||||
"Cannot determine if an uninitialized amount's commodity is annotated");
|
||||
|
||||
assert(! commodity().annotated || commodity().as_annotated().details);
|
||||
return commodity().annotated;
|
||||
}
|
||||
|
||||
annotation_t amount_t::annotation_details() const
|
||||
{
|
||||
if (! quantity)
|
||||
throw_(amount_error,
|
||||
"Cannot return commodity annotation details of an uninitialized amount");
|
||||
|
||||
assert(! commodity().annotated || commodity().as_annotated().details);
|
||||
|
||||
if (commodity().annotated) {
|
||||
|
|
@ -1019,7 +1054,7 @@ void amount_t::parse(std::istream& in, flags_t flags)
|
|||
if (quant.empty())
|
||||
throw_(amount_error, "No quantity specified for amount");
|
||||
|
||||
_init();
|
||||
_init(); // this will reuse a current value
|
||||
|
||||
// Create the commodity if has not already been seen, and update the
|
||||
// precision if something greater was used for the quantity.
|
||||
|
|
@ -1133,6 +1168,9 @@ void amount_t::parse_conversion(const string& larger_str,
|
|||
void amount_t::print(std::ostream& _out, bool omit_commodity,
|
||||
bool full_precision) const
|
||||
{
|
||||
if (! quantity)
|
||||
throw_(amount_error, "Cannot write out an uninitialized amount");
|
||||
|
||||
amount_t base(*this);
|
||||
if (! amount_t::keep_base)
|
||||
base.in_place_unreduce();
|
||||
|
|
@ -1341,6 +1379,9 @@ void amount_t::read(char *& data)
|
|||
|
||||
void amount_t::write(std::ostream& out) const
|
||||
{
|
||||
if (! quantity)
|
||||
throw_(amount_error, "Cannot serialize an uninitialized amount");
|
||||
|
||||
if (commodity_)
|
||||
write_binary_long(out, commodity_->ident);
|
||||
else
|
||||
|
|
@ -1435,11 +1476,7 @@ void amount_t::write_quantity(std::ostream& out) const
|
|||
{
|
||||
char byte;
|
||||
|
||||
if (! quantity) {
|
||||
byte = 0;
|
||||
out.write(&byte, sizeof(byte));
|
||||
return;
|
||||
}
|
||||
assert(quantity);
|
||||
|
||||
if (quantity->index == 0) {
|
||||
quantity->index = ++bigints_index;
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ public:
|
|||
|
||||
bool is_null() const {
|
||||
if (! quantity) {
|
||||
assert(! has_commodity());
|
||||
assert(! commodity_);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -477,6 +477,8 @@ public:
|
|||
|
||||
bool has_commodity() const;
|
||||
void set_commodity(commodity_t& comm) {
|
||||
if (! quantity)
|
||||
*this = 0L;
|
||||
commodity_ = &comm;
|
||||
}
|
||||
void clear_commodity() {
|
||||
|
|
@ -486,6 +488,7 @@ public:
|
|||
amount_t number() const {
|
||||
if (! has_commodity())
|
||||
return *this;
|
||||
|
||||
amount_t temp(*this);
|
||||
temp.clear_commodity();
|
||||
return temp;
|
||||
|
|
|
|||
|
|
@ -34,10 +34,10 @@ void AmountTestCase::testConstructors()
|
|||
amount_t x10(x6);
|
||||
amount_t x11(x8);
|
||||
|
||||
assertEqual(amount_t(0L), x0);
|
||||
assertEqual(amount_t(), x0);
|
||||
assertEqual(amount_t("0"), x0);
|
||||
assertEqual(amount_t("0.0"), x0);
|
||||
assertThrow(amount_t(0L) == x0, amount_error);
|
||||
assertThrow(amount_t() == x0, amount_error);
|
||||
assertThrow(amount_t("0") == x0, amount_error);
|
||||
assertThrow(amount_t("0.0") == x0, amount_error);
|
||||
assertEqual(x2, x1);
|
||||
assertEqual(x5, x1);
|
||||
assertEqual(x7, x1);
|
||||
|
|
@ -108,7 +108,6 @@ void AmountTestCase::testCommodityConstructors()
|
|||
|
||||
void AmountTestCase::testAssignment()
|
||||
{
|
||||
amount_t x0;
|
||||
amount_t x1 = 123456L;
|
||||
amount_t x2 = 123456UL;
|
||||
amount_t x3 = 123.456;
|
||||
|
|
@ -119,7 +118,6 @@ void AmountTestCase::testAssignment()
|
|||
amount_t x9 = x3;
|
||||
amount_t x10 = amount_t(x6);
|
||||
|
||||
assertEqual(amount_t(0L), x0);
|
||||
assertEqual(x2, x1);
|
||||
assertEqual(x5, x1);
|
||||
assertEqual(x7, x1);
|
||||
|
|
@ -128,7 +126,6 @@ void AmountTestCase::testAssignment()
|
|||
assertEqual(x10, x3);
|
||||
assertEqual(x10, x9);
|
||||
|
||||
x0 = amount_t();
|
||||
x1 = 123456L;
|
||||
x2 = 123456UL;
|
||||
x3 = 123.456;
|
||||
|
|
@ -139,7 +136,6 @@ void AmountTestCase::testAssignment()
|
|||
x9 = x3;
|
||||
x10 = amount_t(x6);
|
||||
|
||||
assertEqual(amount_t(0L), x0);
|
||||
assertEqual(x2, x1);
|
||||
assertEqual(x5, x1);
|
||||
assertEqual(x7, x1);
|
||||
|
|
@ -148,7 +144,6 @@ void AmountTestCase::testAssignment()
|
|||
assertEqual(x10, x3);
|
||||
assertEqual(x10, x9);
|
||||
|
||||
assertTrue(x0.valid());
|
||||
assertTrue(x1.valid());
|
||||
assertTrue(x2.valid());
|
||||
assertTrue(x3.valid());
|
||||
|
|
@ -246,12 +241,12 @@ void AmountTestCase::testCommodityEquality()
|
|||
amount_t x10 = "-123.45€";
|
||||
|
||||
assertTrue(x0.is_null());
|
||||
assertTrue(x0.is_zero());
|
||||
assertTrue(x0.is_realzero());
|
||||
assertTrue(x0.sign() == 0);
|
||||
assertTrue(x0.compare(x1) < 0);
|
||||
assertTrue(x0.compare(x2) > 0);
|
||||
assertTrue(x0.compare(x0) == 0);
|
||||
assertThrow(x0.is_zero(), amount_error);
|
||||
assertThrow(x0.is_realzero(), amount_error);
|
||||
assertThrow(x0.sign() == 0, amount_error);
|
||||
assertThrow(x0.compare(x1) < 0, amount_error);
|
||||
assertThrow(x0.compare(x2) > 0, amount_error);
|
||||
assertThrow(x0.compare(x0) == 0, amount_error);
|
||||
|
||||
assertTrue(x1 != x2);
|
||||
assertTrue(x1 != x4);
|
||||
|
|
@ -286,12 +281,12 @@ void AmountTestCase::testComparisons()
|
|||
amount_t x5("-123.45");
|
||||
amount_t x6("123.45");
|
||||
|
||||
assertTrue(x0 > x1);
|
||||
assertTrue(x0 < x2);
|
||||
assertTrue(x0 > x3);
|
||||
assertTrue(x0 < x4);
|
||||
assertTrue(x0 > x5);
|
||||
assertTrue(x0 < x6);
|
||||
assertThrow(x0 > x1, amount_error);
|
||||
assertThrow(x0 < x2, amount_error);
|
||||
assertThrow(x0 > x3, amount_error);
|
||||
assertThrow(x0 < x4, amount_error);
|
||||
assertThrow(x0 > x5, amount_error);
|
||||
assertThrow(x0 < x6, amount_error);
|
||||
|
||||
assertTrue(x1 > x3);
|
||||
assertTrue(x3 <= x5);
|
||||
|
|
@ -317,7 +312,6 @@ void AmountTestCase::testComparisons()
|
|||
|
||||
void AmountTestCase::testCommodityComparisons()
|
||||
{
|
||||
amount_t x0;
|
||||
amount_t x1("$-123");
|
||||
amount_t x2("$123.00");
|
||||
amount_t x3(internalAmount("$-123.4544"));
|
||||
|
|
@ -325,13 +319,6 @@ void AmountTestCase::testCommodityComparisons()
|
|||
amount_t x5("$-123.45");
|
||||
amount_t x6("$123.45");
|
||||
|
||||
assertTrue(x0 > x1);
|
||||
assertTrue(x0 < x2);
|
||||
assertTrue(x0 > x3);
|
||||
assertTrue(x0 < x4);
|
||||
assertTrue(x0 > x5);
|
||||
assertTrue(x0 < x6);
|
||||
|
||||
assertTrue(x1 > x3);
|
||||
assertTrue(x3 <= x5);
|
||||
assertTrue(x3 < x5);
|
||||
|
|
@ -340,7 +327,6 @@ void AmountTestCase::testCommodityComparisons()
|
|||
assertTrue(x3 < x1);
|
||||
assertTrue(x3 < x4);
|
||||
|
||||
assertValid(x0);
|
||||
assertValid(x1);
|
||||
assertValid(x2);
|
||||
assertValid(x3);
|
||||
|
|
@ -847,7 +833,6 @@ void AmountTestCase::testCommodityDivision()
|
|||
|
||||
void AmountTestCase::testNegation()
|
||||
{
|
||||
amount_t x0;
|
||||
amount_t x1(-123456L);
|
||||
amount_t x3(-123.456);
|
||||
amount_t x5("-123456");
|
||||
|
|
@ -856,7 +841,6 @@ void AmountTestCase::testNegation()
|
|||
amount_t x8(string("-123.456"));
|
||||
amount_t x9(- x3);
|
||||
|
||||
assertEqual(amount_t(0L), x0);
|
||||
assertEqual(x5, x1);
|
||||
assertEqual(x7, x1);
|
||||
assertEqual(x6, x3);
|
||||
|
|
@ -868,7 +852,6 @@ void AmountTestCase::testNegation()
|
|||
|
||||
assertEqual(x3, x10);
|
||||
|
||||
assertTrue(x0.valid());
|
||||
assertTrue(x1.valid());
|
||||
assertTrue(x3.valid());
|
||||
assertTrue(x5.valid());
|
||||
|
|
@ -940,7 +923,7 @@ void AmountTestCase::testAbs()
|
|||
amount_t x1(-1234L);
|
||||
amount_t x2(1234L);
|
||||
|
||||
assertEqual(amount_t(), x0.abs());
|
||||
assertThrow(x0.abs(), amount_error);
|
||||
assertEqual(amount_t(1234L), x1.abs());
|
||||
assertEqual(amount_t(1234L), x2.abs());
|
||||
|
||||
|
|
@ -951,15 +934,12 @@ void AmountTestCase::testAbs()
|
|||
|
||||
void AmountTestCase::testCommodityAbs()
|
||||
{
|
||||
amount_t x0;
|
||||
amount_t x1("$-1234.56");
|
||||
amount_t x2("$1234.56");
|
||||
|
||||
assertEqual(amount_t(), x0.abs());
|
||||
assertEqual(amount_t("$1234.56"), x1.abs());
|
||||
assertEqual(amount_t("$1234.56"), x2.abs());
|
||||
|
||||
assertValid(x0);
|
||||
assertValid(x1);
|
||||
assertValid(x2);
|
||||
}
|
||||
|
|
@ -1010,7 +990,7 @@ void AmountTestCase::testFractionalRound()
|
|||
|
||||
assertEqual(amount_t("0.0000000000000000000000000000000000001"),
|
||||
x5.round(37));
|
||||
assertEqual(amount_t(), x5.round(36));
|
||||
assertEqual(amount_t(0L), x5.round(36));
|
||||
|
||||
assertTrue(x1.valid());
|
||||
assertTrue(x2.valid());
|
||||
|
|
@ -1127,7 +1107,7 @@ void AmountTestCase::testSign()
|
|||
amount_t x3("1");
|
||||
amount_t x4("-1");
|
||||
|
||||
assertEqual(x0.sign(), 0);
|
||||
assertThrow(x0.sign(), amount_error);
|
||||
assertTrue(x1.sign() > 0);
|
||||
assertTrue(x2.sign() < 0);
|
||||
assertTrue(x3.sign() > 0);
|
||||
|
|
@ -1142,19 +1122,16 @@ void AmountTestCase::testSign()
|
|||
|
||||
void AmountTestCase::testCommoditySign()
|
||||
{
|
||||
amount_t x0;
|
||||
amount_t x1(internalAmount("$0.0000000000000000000000000000000000001"));
|
||||
amount_t x2(internalAmount("$-0.0000000000000000000000000000000000001"));
|
||||
amount_t x3("$1");
|
||||
amount_t x4("$-1");
|
||||
|
||||
assertFalse(x0.sign());
|
||||
assertTrue(x1.sign() != 0);
|
||||
assertTrue(x2.sign() != 0);
|
||||
assertTrue(x3.sign() > 0);
|
||||
assertTrue(x4.sign() < 0);
|
||||
|
||||
assertValid(x0);
|
||||
assertValid(x1);
|
||||
assertValid(x2);
|
||||
assertValid(x3);
|
||||
|
|
@ -1167,10 +1144,7 @@ void AmountTestCase::testTruth()
|
|||
amount_t x1("1234");
|
||||
amount_t x2("1234.56");
|
||||
|
||||
if (x0)
|
||||
assertTrue(false);
|
||||
else
|
||||
assertTrue(true);
|
||||
assertThrow(x0 ? 1 : 0, amount_error);
|
||||
|
||||
assertTrue(x1);
|
||||
assertTrue(x2);
|
||||
|
|
@ -1204,10 +1178,9 @@ void AmountTestCase::testForZero()
|
|||
amount_t x0;
|
||||
amount_t x1("0.000000000000000000001");
|
||||
|
||||
assertFalse(x0);
|
||||
assertTrue(x1);
|
||||
assertTrue(x0.is_zero());
|
||||
assertTrue(x0.is_realzero());
|
||||
assertThrow(x0.is_zero(), amount_error);
|
||||
assertThrow(x0.is_realzero(), amount_error);
|
||||
assertFalse(x1.is_zero());
|
||||
assertFalse(x1.is_realzero());
|
||||
|
||||
|
|
@ -1271,9 +1244,7 @@ void AmountTestCase::testPrinting()
|
|||
|
||||
{
|
||||
std::ostringstream bufstr;
|
||||
bufstr << x0;
|
||||
|
||||
assertEqual(std::string("0"), bufstr.str());
|
||||
assertThrow(bufstr << x0, amount_error);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -1290,17 +1261,9 @@ void AmountTestCase::testPrinting()
|
|||
|
||||
void AmountTestCase::testCommodityPrinting()
|
||||
{
|
||||
amount_t x0;
|
||||
amount_t x1(internalAmount("$982340823.386238098235098235098235098"));
|
||||
amount_t x2("$982340823.38");
|
||||
|
||||
{
|
||||
std::ostringstream bufstr;
|
||||
bufstr << x0;
|
||||
|
||||
assertEqual(std::string("0"), bufstr.str());
|
||||
}
|
||||
|
||||
{
|
||||
std::ostringstream bufstr;
|
||||
bufstr << x1;
|
||||
|
|
@ -1324,7 +1287,6 @@ void AmountTestCase::testCommodityPrinting()
|
|||
assertEqual(std::string("$964993493285024293.18"), bufstr.str());
|
||||
}
|
||||
|
||||
assertValid(x0);
|
||||
assertValid(x1);
|
||||
assertValid(x2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@ class AmountTestCase(unittest.TestCase):
|
|||
x9 = amount(x3)
|
||||
x10 = amount(x6)
|
||||
|
||||
self.assertEqual(amount(0), x0)
|
||||
self.assertEqual(amount(), x0)
|
||||
self.assertEqual(amount("0"), x0)
|
||||
self.assertEqual(amount("0.0"), x0)
|
||||
self.assertRaises(exceptions.ArithmeticError, operator.eq, amount(0), x0)
|
||||
self.assertRaises(exceptions.ArithmeticError, operator.eq, amount(), x0)
|
||||
self.assertRaises(exceptions.ArithmeticError, operator.eq, amount("0"), x0)
|
||||
self.assertRaises(exceptions.ArithmeticError, operator.eq, amount("0.0"), x0)
|
||||
self.assertEqual(x2, x1)
|
||||
self.assertEqual(x5, x1)
|
||||
self.assertEqual(x6, x3)
|
||||
|
|
@ -98,7 +98,6 @@ class AmountTestCase(unittest.TestCase):
|
|||
self.assertValid(x10)
|
||||
|
||||
def testAssignment(self):
|
||||
x0 = amount()
|
||||
x1 = amount(123456)
|
||||
x2 = amount(123456L)
|
||||
x3 = amount(123.456)
|
||||
|
|
@ -107,14 +106,12 @@ class AmountTestCase(unittest.TestCase):
|
|||
x9 = x3
|
||||
x10 = amount(x6)
|
||||
|
||||
self.assertEqual(amount(0), x0)
|
||||
self.assertEqual(x2, x1)
|
||||
self.assertEqual(x5, x1)
|
||||
self.assertEqual(x6, x3)
|
||||
self.assertEqual(x10, x3)
|
||||
self.assertEqual(x10, x9)
|
||||
|
||||
x0 = amount()
|
||||
x1 = amount(123456)
|
||||
x2 = amount(123456L)
|
||||
x3 = amount(123.456)
|
||||
|
|
@ -123,14 +120,12 @@ class AmountTestCase(unittest.TestCase):
|
|||
x9 = x3
|
||||
x10 = amount(x6)
|
||||
|
||||
self.assertEqual(amount(0), x0)
|
||||
self.assertEqual(x2, x1)
|
||||
self.assertEqual(x5, x1)
|
||||
self.assertEqual(x6, x3)
|
||||
self.assertEqual(x10, x3)
|
||||
self.assertEqual(x10, x9)
|
||||
|
||||
self.assertValid(x0)
|
||||
self.assertValid(x1)
|
||||
self.assertValid(x2)
|
||||
self.assertValid(x3)
|
||||
|
|
@ -217,12 +212,10 @@ class AmountTestCase(unittest.TestCase):
|
|||
x10 = amount("-123.45€")
|
||||
|
||||
self.assertTrue(x0.is_null())
|
||||
self.assertTrue(x0.is_zero())
|
||||
self.assertTrue(x0.is_realzero())
|
||||
self.assertTrue(x0.sign() == 0)
|
||||
self.assertTrue(x0.compare(x1) < 0)
|
||||
self.assertTrue(x0.compare(x2) > 0)
|
||||
self.assertTrue(x0.compare(x0) == 0)
|
||||
self.assertRaises(exceptions.ArithmeticError, amount.is_zero, x0)
|
||||
self.assertRaises(exceptions.ArithmeticError, amount.is_realzero, x0)
|
||||
self.assertRaises(exceptions.ArithmeticError, amount.sign, x0)
|
||||
self.assertRaises(exceptions.ArithmeticError, amount.compare, x0, 0)
|
||||
|
||||
self.assertTrue(x1 != x2)
|
||||
self.assertTrue(x1 != x4)
|
||||
|
|
@ -255,12 +248,12 @@ class AmountTestCase(unittest.TestCase):
|
|||
x5 = amount("-123.45")
|
||||
x6 = amount("123.45")
|
||||
|
||||
self.assertTrue(x0 > x1)
|
||||
self.assertTrue(x0 < x2)
|
||||
self.assertTrue(x0 > x3)
|
||||
self.assertTrue(x0 < x4)
|
||||
self.assertTrue(x0 > x5)
|
||||
self.assertTrue(x0 < x6)
|
||||
self.assertRaises(exceptions.ArithmeticError, operator.gt, x0, x1)
|
||||
self.assertRaises(exceptions.ArithmeticError, operator.lt, x0, x2)
|
||||
self.assertRaises(exceptions.ArithmeticError, operator.gt, x0, x3)
|
||||
self.assertRaises(exceptions.ArithmeticError, operator.lt, x0, x4)
|
||||
self.assertRaises(exceptions.ArithmeticError, operator.gt, x0, x5)
|
||||
self.assertRaises(exceptions.ArithmeticError, operator.lt, x0, x6)
|
||||
|
||||
self.assertTrue(x1 > x3)
|
||||
self.assertTrue(x3 <= x5)
|
||||
|
|
@ -284,7 +277,6 @@ class AmountTestCase(unittest.TestCase):
|
|||
self.assertValid(x6)
|
||||
|
||||
def testCommodityComparisons(self):
|
||||
x0 = amount()
|
||||
x1 = amount("$-123")
|
||||
x2 = amount("$123.00")
|
||||
x3 = amount(internalAmount("$-123.4544"))
|
||||
|
|
@ -292,13 +284,6 @@ class AmountTestCase(unittest.TestCase):
|
|||
x5 = amount("$-123.45")
|
||||
x6 = amount("$123.45")
|
||||
|
||||
self.assertTrue(x0 > x1)
|
||||
self.assertTrue(x0 < x2)
|
||||
self.assertTrue(x0 > x3)
|
||||
self.assertTrue(x0 < x4)
|
||||
self.assertTrue(x0 > x5)
|
||||
self.assertTrue(x0 < x6)
|
||||
|
||||
self.assertTrue(x1 > x3)
|
||||
self.assertTrue(x3 <= x5)
|
||||
self.assertTrue(x3 < x5)
|
||||
|
|
@ -307,7 +292,6 @@ class AmountTestCase(unittest.TestCase):
|
|||
self.assertTrue(x3 < x1)
|
||||
self.assertTrue(x3 < x4)
|
||||
|
||||
self.assertValid(x0)
|
||||
self.assertValid(x1)
|
||||
self.assertValid(x2)
|
||||
self.assertValid(x3)
|
||||
|
|
@ -792,14 +776,12 @@ class AmountTestCase(unittest.TestCase):
|
|||
self.assertValid(x7)
|
||||
|
||||
def testNegation(self):
|
||||
x0 = amount()
|
||||
x1 = amount(-123456)
|
||||
x3 = amount(-123.456)
|
||||
x5 = amount("-123456")
|
||||
x6 = amount("-123.456")
|
||||
x9 = amount(- x3)
|
||||
|
||||
self.assertEqual(amount(0), x0)
|
||||
self.assertEqual(x5, x1)
|
||||
self.assertEqual(x6, x3)
|
||||
self.assertEqual(- x6, x9)
|
||||
|
|
@ -809,7 +791,6 @@ class AmountTestCase(unittest.TestCase):
|
|||
|
||||
self.assertEqual(x3, x10)
|
||||
|
||||
self.assertValid(x0)
|
||||
self.assertValid(x1)
|
||||
self.assertValid(x3)
|
||||
self.assertValid(x5)
|
||||
|
|
@ -875,7 +856,7 @@ class AmountTestCase(unittest.TestCase):
|
|||
x1 = amount(-1234)
|
||||
x2 = amount(1234)
|
||||
|
||||
self.assertEqual(amount(), abs(x0))
|
||||
self.assertRaises(exceptions.ArithmeticError, amount.abs, x0)
|
||||
self.assertEqual(amount(1234), abs(x1))
|
||||
self.assertEqual(amount(1234), abs(x2))
|
||||
|
||||
|
|
@ -884,15 +865,12 @@ class AmountTestCase(unittest.TestCase):
|
|||
self.assertValid(x2)
|
||||
|
||||
def testCommodityAbs(self):
|
||||
x0 = amount()
|
||||
x1 = amount("$-1234.56")
|
||||
x2 = amount("$1234.56")
|
||||
|
||||
self.assertEqual(amount(), abs(x0))
|
||||
self.assertEqual(amount("$1234.56"), abs(x1))
|
||||
self.assertEqual(amount("$1234.56"), abs(x2))
|
||||
|
||||
self.assertValid(x0)
|
||||
self.assertValid(x1)
|
||||
self.assertValid(x2)
|
||||
|
||||
|
|
@ -941,7 +919,7 @@ class AmountTestCase(unittest.TestCase):
|
|||
|
||||
self.assertEqual(amount("0.0000000000000000000000000000000000001"),
|
||||
x5.round(37))
|
||||
self.assertEqual(amount(), x5.round(36))
|
||||
self.assertEqual(amount(0), x5.round(36))
|
||||
|
||||
self.assertValid(x1)
|
||||
self.assertValid(x2)
|
||||
|
|
@ -1050,7 +1028,7 @@ class AmountTestCase(unittest.TestCase):
|
|||
x3 = amount("1")
|
||||
x4 = amount("-1")
|
||||
|
||||
self.assertEqual(x0.sign(), 0)
|
||||
self.assertRaises(exceptions.ArithmeticError, amount.sign, x0)
|
||||
self.assertTrue(x1.sign() > 0)
|
||||
self.assertTrue(x2.sign() < 0)
|
||||
self.assertTrue(x3.sign() > 0)
|
||||
|
|
@ -1063,19 +1041,16 @@ class AmountTestCase(unittest.TestCase):
|
|||
self.assertValid(x4)
|
||||
|
||||
def testCommoditySign(self):
|
||||
x0 = amount()
|
||||
x1 = amount(internalAmount("$0.0000000000000000000000000000000000001"))
|
||||
x2 = amount(internalAmount("$-0.0000000000000000000000000000000000001"))
|
||||
x3 = amount("$1")
|
||||
x4 = amount("$-1")
|
||||
|
||||
self.assertFalse(x0.sign())
|
||||
self.assertTrue(x1.sign() != 0)
|
||||
self.assertTrue(x2.sign() != 0)
|
||||
self.assertTrue(x3.sign() > 0)
|
||||
self.assertTrue(x4.sign() < 0)
|
||||
|
||||
self.assertValid(x0)
|
||||
self.assertValid(x1)
|
||||
self.assertValid(x2)
|
||||
self.assertValid(x3)
|
||||
|
|
@ -1086,7 +1061,7 @@ class AmountTestCase(unittest.TestCase):
|
|||
x1 = amount("1234")
|
||||
x2 = amount("1234.56")
|
||||
|
||||
self.assertFalse(x0)
|
||||
self.assertRaises(exceptions.ArithmeticError, operator.truth, x0)
|
||||
self.assertTrue(x1)
|
||||
self.assertTrue(x2)
|
||||
|
||||
|
|
@ -1115,10 +1090,9 @@ class AmountTestCase(unittest.TestCase):
|
|||
x0 = amount()
|
||||
x1 = amount("0.000000000000000000001")
|
||||
|
||||
self.assertFalse(x0)
|
||||
self.assertTrue(x1)
|
||||
self.assertTrue(x0.is_zero())
|
||||
self.assertTrue(x0.is_realzero())
|
||||
self.assertRaises(exceptions.ArithmeticError, amount.is_zero, x0)
|
||||
self.assertRaises(exceptions.ArithmeticError, amount.is_realzero, x0)
|
||||
self.assertFalse(x1.is_zero())
|
||||
self.assertFalse(x1.is_realzero())
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue