Correct display of amounts with keep_precision
Fixes #167 / 1D275740-D1A6-42B7-BDE4-F2F85E30CE8E
This commit is contained in:
parent
90d5ef83b6
commit
cbc0a125c0
3 changed files with 217 additions and 14 deletions
|
|
@ -47,6 +47,8 @@ static mpz_t temp;
|
|||
static mpq_t tempq;
|
||||
static mpfr_t tempf;
|
||||
static mpfr_t tempfb;
|
||||
static mpfr_t tempfnum;
|
||||
static mpfr_t tempfden;
|
||||
#endif
|
||||
|
||||
struct amount_t::bigint_t : public supports_flags<>
|
||||
|
|
@ -111,7 +113,7 @@ bool amount_t::is_initialized = false;
|
|||
namespace {
|
||||
void stream_out_mpq(std::ostream& out,
|
||||
mpq_t quant,
|
||||
amount_t::precision_t prec,
|
||||
amount_t::precision_t precision,
|
||||
int zeros_prec = -1,
|
||||
const optional<commodity_t&>& comm = none)
|
||||
{
|
||||
|
|
@ -125,17 +127,39 @@ namespace {
|
|||
|
||||
// Convert the rational number to a floating-point, extending the
|
||||
// floating-point to a large enough size to get a precise answer.
|
||||
const std::size_t bits = (mpz_sizeinbase(mpq_numref(quant), 2) +
|
||||
mpz_sizeinbase(mpq_denref(quant), 2));
|
||||
mpfr_set_prec(tempfb, bits + amount_t::extend_by_digits*8);
|
||||
mpfr_set_q(tempfb, quant, GMP_RNDN);
|
||||
|
||||
if (mpfr_asprintf(&buf, "%.*Rf", prec, tempfb) < 0)
|
||||
mp_prec_t num_prec = mpz_sizeinbase(mpq_numref(quant), 2);
|
||||
num_prec += amount_t::extend_by_digits*64;
|
||||
if (num_prec < MPFR_PREC_MIN)
|
||||
num_prec = MPFR_PREC_MIN;
|
||||
DEBUG("amount.convert", "num prec = " << num_prec);
|
||||
|
||||
mpfr_set_prec(tempfnum, num_prec);
|
||||
mpfr_set_z(tempfnum, mpq_numref(quant), GMP_RNDN);
|
||||
|
||||
mp_prec_t den_prec = mpz_sizeinbase(mpq_denref(quant), 2);
|
||||
den_prec += amount_t::extend_by_digits*64;
|
||||
if (den_prec < MPFR_PREC_MIN)
|
||||
den_prec = MPFR_PREC_MIN;
|
||||
DEBUG("amount.convert", "den prec = " << den_prec);
|
||||
|
||||
mpfr_set_prec(tempfden, den_prec);
|
||||
mpfr_set_z(tempfden, mpq_denref(quant), GMP_RNDN);
|
||||
|
||||
mpfr_set_prec(tempfb, num_prec + den_prec);
|
||||
mpfr_div(tempfb, tempfnum, tempfden, GMP_RNDN);
|
||||
|
||||
char bigbuf[4096];
|
||||
mpfr_sprintf(bigbuf, "%.RNf", tempfb);
|
||||
DEBUG("amount.convert", "num/den = " << bigbuf);
|
||||
|
||||
if (mpfr_asprintf(&buf, "%.*RNf", precision, tempfb) < 0)
|
||||
throw_(amount_error,
|
||||
_("Cannot output amount to a floating-point representation"));
|
||||
|
||||
DEBUG("amount.convert",
|
||||
"mpfr_print = " << buf << " (precision " << prec << ")");
|
||||
DEBUG("amount.convert", "mpfr_print = " << buf
|
||||
<< " (precision " << precision
|
||||
<< ", zeros_prec " << zeros_prec << ")");
|
||||
|
||||
if (zeros_prec >= 0) {
|
||||
string::size_type index = std::strlen(buf);
|
||||
|
|
@ -211,6 +235,8 @@ void amount_t::initialize()
|
|||
mpq_init(tempq);
|
||||
mpfr_init(tempf);
|
||||
mpfr_init(tempfb);
|
||||
mpfr_init(tempfnum);
|
||||
mpfr_init(tempfden);
|
||||
|
||||
commodity_pool_t::current_pool.reset(new commodity_pool_t);
|
||||
|
||||
|
|
@ -238,6 +264,8 @@ void amount_t::shutdown()
|
|||
mpq_clear(tempq);
|
||||
mpfr_clear(tempf);
|
||||
mpfr_clear(tempfb);
|
||||
mpfr_clear(tempfnum);
|
||||
mpfr_clear(tempfden);
|
||||
|
||||
commodity_pool_t::current_pool.reset();
|
||||
|
||||
|
|
@ -556,12 +584,10 @@ amount_t::precision_t amount_t::display_precision() const
|
|||
|
||||
commodity_t& comm(commodity());
|
||||
|
||||
if (! comm || keep_precision())
|
||||
return quantity->prec;
|
||||
else if (comm.precision() != quantity->prec)
|
||||
if (comm && ! keep_precision())
|
||||
return comm.precision();
|
||||
else
|
||||
return quantity->prec;
|
||||
return comm ? std::max(quantity->prec, comm.precision()) : quantity->prec;
|
||||
}
|
||||
|
||||
void amount_t::in_place_negate()
|
||||
|
|
@ -643,7 +669,7 @@ void amount_t::in_place_floor()
|
|||
_dup();
|
||||
|
||||
std::ostringstream out;
|
||||
stream_out_mpq(out, MP(quantity), 0);
|
||||
stream_out_mpq(out, MP(quantity), precision_t(0));
|
||||
|
||||
mpq_set_str(MP(quantity), out.str().c_str(), 10);
|
||||
}
|
||||
|
|
|
|||
177
test/regress/1D275740.test
Normal file
177
test/regress/1D275740.test
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
print
|
||||
<<<
|
||||
D 1.200,40 €
|
||||
|
||||
1999/11/01 * Achat
|
||||
Actif:SSB 125 STK
|
||||
Actif:SSB -1672,42 $
|
||||
|
||||
1999/11/04 * Vente
|
||||
Actif:SSB -125 STK
|
||||
Dépense:SSB:Commissions 55,07 $
|
||||
Actif:SSB 1821,54 $
|
||||
|
||||
2001/05/01 * Vente
|
||||
Actif:SSEA -188,7974 STK @ 14,200 $
|
||||
Dépense:SSEA:Commissions 19,60 $
|
||||
Actif:SSEA 2661,32 $
|
||||
|
||||
2001/12/21 * Achat
|
||||
Actif:LPG 7,34316 AMD @ 200,340 €
|
||||
Actif:LPG -1471,13 €
|
||||
|
||||
2002/12/31 * Réinv. des dividendes
|
||||
Actif:LPG 0,03032 AMD @ 135,060 €
|
||||
Revenu:Dividende:AMD -4,10 €
|
||||
|
||||
2003/12/31 * Réinv. des dividendes
|
||||
Actif:LPG 0,02356 AMD @ 147,830 €
|
||||
Revenu:Dividende:AMD -3,48 €
|
||||
|
||||
2004/02/17 * Vente
|
||||
Actif:LPG -7,39704 AMD @ 148,860 €
|
||||
Actif:LPG 1101,12 €
|
||||
|
||||
2005/12/31 * Réinv. des dividendes
|
||||
Actif:LPG 0,87704 LAPD @ 22,680 €
|
||||
Revenu:Dividende:LAPD -19,89 €
|
||||
|
||||
2006/06/30 * Achat
|
||||
Actif:CPE 54,7328 PM @ 33,200 €
|
||||
Actif:CPE -1817,13 €
|
||||
|
||||
2006/06/30 * Achat
|
||||
Actif:CPE 13,8913 PM @ 33,200 €
|
||||
Actif:CPE -461,19 €
|
||||
|
||||
2007/04/01 Achat
|
||||
Actif:SV 0,2087 CE @ 622,900 €
|
||||
Actif:BC -130,00 €
|
||||
|
||||
2007/12/27 Vente
|
||||
Actif:SV -0,2086 EA @ 183,800 €
|
||||
Actif:SV 38,34 €
|
||||
|
||||
2008/01/01 Achat
|
||||
Actif:SV 0,1757 CE @ 739,900 €
|
||||
Actif:BC -130,00 €
|
||||
|
||||
2008/02/01 Achat
|
||||
Actif:SV 3,1863 EA @ 163,200 €
|
||||
Actif:BC -520,00 €
|
||||
|
||||
2008/05/01 Achat
|
||||
Actif:SV 0,2599 CE @ 654,100 €
|
||||
Actif:BC -170,00 €
|
||||
|
||||
2008/10/30 Vente
|
||||
Actif:SV -0,0405 CD @ 155,800 €
|
||||
Actif:SV 6,31 €
|
||||
|
||||
2008/12/31 Vente
|
||||
Actif:SV -0,0357 MFE @ 259,100 €
|
||||
Actif:SV 9,25 €
|
||||
|
||||
2009/06/29 Vente
|
||||
Actif:SV -0,0786 CD @ 155,600 €
|
||||
Actif:SV 12,23 €
|
||||
|
||||
2009/07/30 Vente
|
||||
Actif:SV -0,0417 MFE @ 321,100 €
|
||||
Actif:SV 13,39 €
|
||||
|
||||
2009/08/01 Achat
|
||||
Actif:SV 1,0204 MFE @ 333,200 €
|
||||
Actif:BC -340,00 €
|
||||
|
||||
2009/09/29 Vente
|
||||
Actif:SV -0,0415 MFE @ 358,800 €
|
||||
Actif:SV 14,89 €
|
||||
>>>1
|
||||
1999/11/01 * Achat
|
||||
Actif:SSB 125,0000 STK @ 13,37936 $
|
||||
Actif:SSB -1672,42 $
|
||||
|
||||
1999/11/04 * Vente
|
||||
Actif:SSB -125,0000 STK @ 15,01288 $
|
||||
Dépense:SSB:Commissions 55,07 $
|
||||
Actif:SSB 1821,54 $
|
||||
|
||||
2001/05/01 * Vente
|
||||
Actif:SSEA -188,7974 STK @ 14,20 $
|
||||
Dépense:SSEA:Commissions 19,60 $
|
||||
Actif:SSEA 2661,32 $
|
||||
|
||||
2001/12/21 * Achat
|
||||
Actif:LPG 7,34316 AMD @ 200,34 €
|
||||
Actif:LPG -1.471,13 €
|
||||
|
||||
2002/12/31 * Réinv. des dividendes
|
||||
Actif:LPG 0,03032 AMD @ 135,06 €
|
||||
Revenu:Dividende:AMD -4,10 €
|
||||
|
||||
2003/12/31 * Réinv. des dividendes
|
||||
Actif:LPG 0,02356 AMD @ 147,83 €
|
||||
Revenu:Dividende:AMD -3,48 €
|
||||
|
||||
2004/02/17 * Vente
|
||||
Actif:LPG -7,39704 AMD @ 148,86 €
|
||||
Actif:LPG 1.101,12 €
|
||||
|
||||
2005/12/31 * Réinv. des dividendes
|
||||
Actif:LPG 0,87704 LAPD @ 22,68 €
|
||||
Revenu:Dividende:LAPD -19,89 €
|
||||
|
||||
2006/06/30 * Achat
|
||||
Actif:CPE 54,7328 PM @ 33,20 €
|
||||
Actif:CPE -1.817,13 €
|
||||
|
||||
2006/06/30 * Achat
|
||||
Actif:CPE 13,8913 PM @ 33,20 €
|
||||
Actif:CPE -461,19 €
|
||||
|
||||
2007/04/01 Achat
|
||||
Actif:SV 0,2087 CE @ 622,90 €
|
||||
Actif:BC -130,00 €
|
||||
|
||||
2007/12/27 Vente
|
||||
Actif:SV -0,2086 EA @ 183,80 €
|
||||
Actif:SV 38,34 €
|
||||
|
||||
2008/01/01 Achat
|
||||
Actif:SV 0,1757 CE @ 739,90 €
|
||||
Actif:BC -130,00 €
|
||||
|
||||
2008/02/01 Achat
|
||||
Actif:SV 3,1863 EA @ 163,20 €
|
||||
Actif:BC -520,00 €
|
||||
|
||||
2008/05/01 Achat
|
||||
Actif:SV 0,2599 CE @ 654,10 €
|
||||
Actif:BC -170,00 €
|
||||
|
||||
2008/10/30 Vente
|
||||
Actif:SV -0,0405 CD @ 155,80 €
|
||||
Actif:SV 6,31 €
|
||||
|
||||
2008/12/31 Vente
|
||||
Actif:SV -0,0357 MFE @ 259,10 €
|
||||
Actif:SV 9,25 €
|
||||
|
||||
2009/06/29 Vente
|
||||
Actif:SV -0,0786 CD @ 155,60 €
|
||||
Actif:SV 12,23 €
|
||||
|
||||
2009/07/30 Vente
|
||||
Actif:SV -0,0417 MFE @ 321,10 €
|
||||
Actif:SV 13,39 €
|
||||
|
||||
2009/08/01 Achat
|
||||
Actif:SV 1,0204 MFE @ 333,20 €
|
||||
Actif:BC -340,00 €
|
||||
|
||||
2009/09/29 Vente
|
||||
Actif:SV -0,0415 MFE @ 358,80 €
|
||||
Actif:SV 14,89 €
|
||||
>>>2
|
||||
=== 0
|
||||
|
|
@ -15,6 +15,6 @@ While balancing transaction from "$FILE", lines 3-5:
|
|||
Unbalanced remainder is:
|
||||
100.00 USD
|
||||
Amount to balance against:
|
||||
1,600.0 USD
|
||||
1,600.00 USD
|
||||
Error: Transaction does not balance
|
||||
=== 1
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue