First round of using boost/operators is done.
This commit is contained in:
parent
9e80a6fbcc
commit
103881ff80
7 changed files with 73 additions and 25 deletions
|
|
@ -84,7 +84,7 @@ class amount_t::bigint_t
|
|||
~bigint_t();
|
||||
};
|
||||
|
||||
unsigned int sizeof_bigint_t() {
|
||||
std::size_t sizeof_bigint_t() {
|
||||
return sizeof(amount_t::bigint_t);
|
||||
}
|
||||
|
||||
|
|
@ -216,7 +216,7 @@ void amount_t::_copy(const amount_t& amt)
|
|||
commodity_ = amt.commodity_;
|
||||
}
|
||||
|
||||
void amount_t::_resize(unsigned int prec)
|
||||
void amount_t::_resize(precision_t prec)
|
||||
{
|
||||
assert(prec < 256);
|
||||
|
||||
|
|
@ -560,7 +560,7 @@ amount_t& amount_t::operator*=(const amount_t& amt)
|
|||
commodity_ = amt.commodity_;
|
||||
|
||||
if (has_commodity() && ! (quantity->flags & BIGINT_KEEP_PREC)) {
|
||||
unsigned int comm_prec = commodity().precision();
|
||||
precision_t comm_prec = commodity().precision();
|
||||
if (quantity->prec > comm_prec + 6U) {
|
||||
mpz_round(MPZ(quantity), MPZ(quantity), quantity->prec, comm_prec + 6U);
|
||||
quantity->prec = comm_prec + 6U;
|
||||
|
|
@ -612,7 +612,7 @@ amount_t& amount_t::operator/=(const amount_t& amt)
|
|||
// plus six places.
|
||||
|
||||
if (has_commodity() && ! (quantity->flags & BIGINT_KEEP_PREC)) {
|
||||
unsigned int comm_prec = commodity().precision();
|
||||
precision_t comm_prec = commodity().precision();
|
||||
if (quantity->prec > comm_prec + 6U) {
|
||||
mpz_round(MPZ(quantity), MPZ(quantity), quantity->prec, comm_prec + 6U);
|
||||
quantity->prec = comm_prec + 6U;
|
||||
|
|
@ -650,6 +650,44 @@ bool amount_t::zero() const
|
|||
return realzero();
|
||||
}
|
||||
|
||||
long amount_t::to_long() const
|
||||
{
|
||||
if (! quantity)
|
||||
return 0;
|
||||
|
||||
mpz_set(temp, MPZ(quantity));
|
||||
mpz_ui_pow_ui(divisor, 10, quantity->prec);
|
||||
mpz_tdiv_q(temp, temp, divisor);
|
||||
|
||||
return mpz_get_si(temp);
|
||||
}
|
||||
|
||||
double amount_t::to_double() const
|
||||
{
|
||||
if (! quantity)
|
||||
return 0.0;
|
||||
|
||||
mpz_t remainder;
|
||||
mpz_init(remainder);
|
||||
|
||||
mpz_set(temp, MPZ(quantity));
|
||||
mpz_ui_pow_ui(divisor, 10, quantity->prec);
|
||||
mpz_tdiv_qr(temp, remainder, temp, divisor);
|
||||
|
||||
char * quotient_s = mpz_get_str(NULL, 10, temp);
|
||||
char * remainder_s = mpz_get_str(NULL, 10, remainder);
|
||||
|
||||
std::ostringstream num;
|
||||
num << quotient_s << '.' << remainder_s;
|
||||
|
||||
std::free(quotient_s);
|
||||
std::free(remainder_s);
|
||||
|
||||
mpz_clear(remainder);
|
||||
|
||||
return lexical_cast<double>(num.str());
|
||||
}
|
||||
|
||||
amount_t amount_t::value(const moment_t& moment) const
|
||||
{
|
||||
if (quantity) {
|
||||
|
|
@ -660,7 +698,7 @@ amount_t amount_t::value(const moment_t& moment) const
|
|||
return *this;
|
||||
}
|
||||
|
||||
amount_t amount_t::round(unsigned int prec) const
|
||||
amount_t amount_t::round(precision_t prec) const
|
||||
{
|
||||
amount_t t = *this;
|
||||
|
||||
|
|
|
|||
28
src/amount.h
28
src/amount.h
|
|
@ -66,18 +66,23 @@ DECLARE_EXCEPTION(amount_error);
|
|||
* math, and also for uncommoditized math. In the commoditized case,
|
||||
* commodities keep track of how they are used, and will always
|
||||
* display back to the user after the same fashion. For
|
||||
* uncommoditized numbers, no display truncation is ever done.
|
||||
* Internally, precision is always kept to an excessive degree.
|
||||
* uncommoditized numbers, no display truncation is ever done. In
|
||||
* both cases, internal precision is always kept to an excessive
|
||||
* degree.
|
||||
*/
|
||||
class amount_t
|
||||
: public ordered_field_operators<amount_t,
|
||||
ordered_field_operators<amount_t, long,
|
||||
ordered_field_operators<amount_t, unsigned long,
|
||||
ordered_field_operators<amount_t, double> > > >
|
||||
class amount_t
|
||||
: public ordered_field_operators<amount_t,
|
||||
ordered_field_operators<amount_t, long,
|
||||
ordered_field_operators<amount_t, unsigned long,
|
||||
ordered_field_operators<amount_t, double> > > >
|
||||
{
|
||||
public:
|
||||
class bigint_t;
|
||||
|
||||
// jww (2007-05-01): Change my uses of unsigned int to use this type
|
||||
// for precision values. Or perhaps just std::size_t?
|
||||
typedef uint_least16_t precision_t;
|
||||
|
||||
static void initialize();
|
||||
static void shutdown();
|
||||
|
||||
|
|
@ -92,7 +97,7 @@ protected:
|
|||
void _copy(const amount_t& amt);
|
||||
void _release();
|
||||
void _dup();
|
||||
void _resize(unsigned int prec);
|
||||
void _resize(precision_t prec);
|
||||
void _clear();
|
||||
|
||||
bigint_t * quantity;
|
||||
|
|
@ -170,6 +175,9 @@ public:
|
|||
|
||||
// test for truth, zero and non-zero
|
||||
operator bool() const {
|
||||
return nonzero();
|
||||
}
|
||||
bool nonzero() const {
|
||||
return ! zero();
|
||||
}
|
||||
|
||||
|
|
@ -180,6 +188,8 @@ public:
|
|||
}
|
||||
|
||||
// conversion methods
|
||||
long to_long() const;
|
||||
double to_double() const;
|
||||
string to_string() const;
|
||||
string to_fullstring() const;
|
||||
string quantity_string() const;
|
||||
|
|
@ -220,7 +230,7 @@ public:
|
|||
optional<string> tag() const;
|
||||
|
||||
// general methods
|
||||
amount_t round(unsigned int prec) const;
|
||||
amount_t round(precision_t prec) const;
|
||||
amount_t round() const;
|
||||
amount_t unround() const;
|
||||
amount_t value(const moment_t& moment) const;
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ typedef std::pair<const string, commodity_t *> commodities_pair;
|
|||
|
||||
typedef std::vector<commodity_t *> commodities_array;
|
||||
|
||||
class commodity_t
|
||||
class commodity_t : public equality_comparable<commodity_t>
|
||||
{
|
||||
friend class annotated_commodity_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -147,9 +147,9 @@ void export_amount()
|
|||
|
||||
.def(! self)
|
||||
|
||||
.def(self_ns::int_(self))
|
||||
.def(self_ns::float_(self))
|
||||
|
||||
.def("__int__", &amount_t::to_long)
|
||||
.def("__float__", &amount_t::to_double)
|
||||
.def("__nonzero__", &amount_t::nonzero)
|
||||
.def("__abs__", &amount_t::abs)
|
||||
.def("__str__", &amount_t::to_string)
|
||||
.def("__repr__", &amount_t::to_fullstring)
|
||||
|
|
|
|||
|
|
@ -415,8 +415,8 @@ void BasicAmountTestCase::testIntegerConversion()
|
|||
amount_t x1(123456L);
|
||||
|
||||
assertEqual(true, bool(x1));
|
||||
assertEqual(123456L, long(x1));
|
||||
assertEqual(123456.0, double(x1));
|
||||
assertEqual(123456L, x1.to_long());
|
||||
assertEqual(123456.0, x1.to_double());
|
||||
assertEqual(string("123456"), x1.to_string());
|
||||
assertEqual(string("123456"), x1.quantity_string());
|
||||
|
||||
|
|
@ -428,8 +428,8 @@ void BasicAmountTestCase::testFractionalConversion()
|
|||
amount_t x1(1234.56);
|
||||
|
||||
assertEqual(true, bool(x1));
|
||||
assertEqual(1234L, long(x1));
|
||||
assertEqual(1234.56, double(x1));
|
||||
assertEqual(1234L, x1.to_long());
|
||||
assertEqual(1234.56, x1.to_double());
|
||||
assertEqual(string("1234.56"), x1.to_string());
|
||||
assertEqual(string("1234.56"), x1.quantity_string());
|
||||
|
||||
|
|
|
|||
|
|
@ -465,8 +465,8 @@ void CommodityAmountTestCase::testConversion()
|
|||
amount_t x1("$1234.56");
|
||||
|
||||
assertEqual(true, bool(x1));
|
||||
assertEqual(1234L, long(x1));
|
||||
assertEqual(1234.56, double(x1));
|
||||
assertEqual(1234L, x1.to_long());
|
||||
assertEqual(1234.56, x1.to_double());
|
||||
assertEqual(string("$1234.56"), x1.to_string());
|
||||
assertEqual(string("1234.56"), x1.quantity_string());
|
||||
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ class CommodityAmountTestCase(unittest.TestCase):
|
|||
x9 = amount("123.45€")
|
||||
x10 = amount("-123.45€")
|
||||
|
||||
self.assertTrue(x0.null())
|
||||
self.assertTrue(x0.is_null())
|
||||
self.assertTrue(x0.zero())
|
||||
self.assertTrue(x0.realzero())
|
||||
self.assertTrue(x0.sign() == 0)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue