Bill Gribble's patch.

* src/engine/gnc-numeric.{c,h}, src/scm/gnc-numeric.scm: add
        support for a new auto-denom type, GNC_DENOM_SIGFIGS(x), where x
        is the number of "significant figures" you want in the output.
        This means that the output denominator will always be a poewr of
        10, but which power is determined by the magnitude of the
        argument.

        * src/engine/Transaction.c, src/gnc-exp-parser.c,
        src/gnc-ui-util.c: make minor changes to use GNC_DENOM_SIGFIGS
        where appropriate.

        * src/gnome/dialog-account-picker.{c,h}: totally rewritten QIF
        import account picker.  this one is much less likely to get you
        into trouble.  Still some rough edges but MUCH better than
        the old one.

        * src/gnome/druid-qif-import.c: fixes.  Add memo/payee matching
        (but it's not hooked up to the import yet so don't get that
        excited).

        * src/scm/qif-import/qif-dialog-utils.scm: memo mapping stuff,
        i18n fixes.

        * src/scm/qif-import/qif-to-gnc.scm: update error catching; print
        backtrace on failure.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@3644 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Dave Peticolas
2001-02-12 22:46:55 +00:00
parent 85a79ab409
commit 2caac7636b
19 changed files with 1359 additions and 860 deletions

View File

@@ -64,9 +64,7 @@
*/
int force_double_entry = 0;
/* arbitrary price per share increment FIXME */
#define PRICE_DENOM 1000000
#define PRICE_SIGFIGS 6
/* This static indicates the debugging module that this .o belongs to. */
static short module = MOD_ENGINE;
@@ -377,7 +375,8 @@ DxaccSplitSetSharePriceAndAmount (Split *s, double price, double amt)
{
xaccSplitSetSharePriceAndAmount
(s,
double_to_gnc_numeric(price, PRICE_DENOM, GNC_RND_ROUND),
double_to_gnc_numeric(price, GNC_DENOM_AUTO,
GNC_DENOM_SIGFIGS(PRICE_SIGFIGS) | GNC_RND_ROUND),
double_to_gnc_numeric(amt, get_security_denom(s), GNC_RND_ROUND));
}
@@ -399,7 +398,9 @@ void
DxaccSplitSetSharePrice (Split *s, double amt)
{
xaccSplitSetSharePrice
(s, double_to_gnc_numeric(amt, PRICE_DENOM, GNC_RND_ROUND));
(s, double_to_gnc_numeric(amt, GNC_DENOM_AUTO,
GNC_DENOM_SIGFIGS(PRICE_SIGFIGS) |
GNC_RND_ROUND));
}
void
@@ -428,7 +429,7 @@ DxaccSplitSetShareAmount (Split *s, double damt)
GNC_DENOM_REDUCE);
}
else {
old_price = gnc_numeric_create(PRICE_DENOM, PRICE_DENOM);
old_price = gnc_numeric_create(1, 1);
}
s->damount = gnc_numeric_convert(amt, get_security_denom(s),
@@ -465,7 +466,7 @@ DxaccSplitSetValue (Split *s, double damt)
GNC_DENOM_REDUCE);
}
else {
old_price = gnc_numeric_create(PRICE_DENOM, PRICE_DENOM);
old_price = gnc_numeric_create(1, 1);
}
s->value = gnc_numeric_convert(amt, get_currency_denom(s),
@@ -2185,11 +2186,13 @@ xaccSplitGetValue (Split * split) {
gnc_numeric
xaccSplitGetSharePrice (Split * split) {
if(!split || gnc_numeric_zero_p(split->damount)) {
return gnc_numeric_create(PRICE_DENOM, PRICE_DENOM);
return gnc_numeric_create(1, 1);
}
return gnc_numeric_div(split->value,
split->damount,
PRICE_DENOM, GNC_RND_ROUND);
GNC_DENOM_AUTO,
GNC_DENOM_SIGFIGS(PRICE_SIGFIGS) |
GNC_RND_ROUND);
}
/********************************************************************\

View File

@@ -475,6 +475,8 @@ gnc_numeric_convert(gnc_numeric in, gint64 denom, gint how) {
gint64 remainder;
gint64 sign;
gint denom_neg=0;
double ratio, logratio;
double sigfigs;
if(gnc_numeric_check(in)) {
return gnc_numeric_error(GNC_ERROR_ARG);
@@ -500,6 +502,23 @@ gnc_numeric_convert(gnc_numeric in, gint64 denom, gint how) {
}
break;
case GNC_DENOM_SIGFIG:
ratio = gnc_numeric_to_double(in);
logratio = log10(ratio);
logratio = ((logratio > 0.0) ?
(floor(logratio)+1.0) : (ceil(logratio)));
sigfigs = GNC_NUMERIC_GET_SIGFIGS(how);
if(sigfigs-logratio >= 0) {
denom = (gint64)(pow(10, sigfigs-logratio));
}
else {
denom = -((gint64)(pow(10, logratio-sigfigs)));
}
how = how & ~GNC_DENOM_SIGFIG & ~GNC_NUMERIC_SIGFIGS_MASK;
break;
case GNC_DENOM_LCD:
/* this is a no-op. */
default:
@@ -573,7 +592,7 @@ gnc_numeric_convert(gnc_numeric in, gint64 denom, gint how) {
out.num = out.num + 1;
}
}
else if((2 * remainder * denom) > in.denom) {
else if((2 * remainder) > temp.denom) {
out.num = out.num + 1;
}
break;
@@ -584,7 +603,7 @@ gnc_numeric_convert(gnc_numeric in, gint64 denom, gint how) {
out.num = out.num + 1;
}
}
else if((2 * remainder * denom) >= in.denom) {
else if((2 * remainder ) >= temp.denom) {
out.num = out.num + 1;
}
break;
@@ -601,10 +620,10 @@ gnc_numeric_convert(gnc_numeric in, gint64 denom, gint how) {
}
}
else {
if((2 * remainder * denom) > in.denom) {
if((2 * remainder ) > temp.denom) {
out.num = out.num + 1;
}
else if((2 * remainder * denom) == in.denom) {
else if((2 * remainder) == temp.denom) {
if(out.num % 2) {
out.num = out.num + 1;
}
@@ -780,6 +799,23 @@ double_to_gnc_numeric(double in, gint64 denom, gint how) {
gint64 int_part=0;
double frac_part;
gint64 frac_int=0;
double logval;
double sigfigs;
if((denom == GNC_DENOM_AUTO) && (how & GNC_DENOM_SIGFIG)) {
logval = log10(in);
logval = ((logval > 0.0) ?
(floor(logval)+1.0) : (ceil(logval)));
sigfigs = GNC_NUMERIC_GET_SIGFIGS(how);
if(sigfigs-logval >= 0) {
denom = (gint64)(pow(10, sigfigs-logval));
}
else {
denom = -((gint64)(pow(10, logval-sigfigs)));
}
how = how & ~GNC_DENOM_SIGFIG & ~GNC_NUMERIC_SIGFIGS_MASK;
}
int_part = (gint64)(floor(fabs(in)));
frac_part = in - (double)int_part;
@@ -787,7 +823,7 @@ double_to_gnc_numeric(double in, gint64 denom, gint how) {
int_part = int_part * denom;
frac_part = frac_part * (double)denom;
switch(how) {
switch(how & GNC_NUMERIC_RND_MASK) {
case GNC_RND_FLOOR:
frac_int = (gint64)floor(frac_part);
break;
@@ -853,7 +889,7 @@ gnc_numeric_create(gint64 num, gint64 denom) {
gnc_numeric
gnc_numeric_error(int error_code) {
if(abs(error_code) < 5) {
PERR("%s", _numeric_error_strings[ - error_code]);
// PERR("%s", _numeric_error_strings[ - error_code]);
}
return gnc_numeric_create(error_code, 0LL);
}
@@ -1180,7 +1216,35 @@ main(int argc, char ** argv) {
gnc_numeric_print(b), gnc_numeric_print(d),
gnc_numeric_print(gnc_numeric_add(b, d, GNC_DENOM_AUTO,
GNC_DENOM_LCD)));
printf("float to 6 sigfigs: %s\n",
gnc_numeric_print(double_to_gnc_numeric(1.1234567890123,
GNC_DENOM_AUTO,
GNC_DENOM_SIGFIGS(6) |
GNC_RND_ROUND)));
printf("float to 6 sigfigs: %s\n",
gnc_numeric_print(double_to_gnc_numeric(.011234567890123,
GNC_DENOM_AUTO,
GNC_DENOM_SIGFIGS(6) |
GNC_RND_ROUND)));
printf("float to 6 sigfigs: %s\n",
gnc_numeric_print(double_to_gnc_numeric(1123.4567890123,
GNC_DENOM_AUTO,
GNC_DENOM_SIGFIGS(6) |
GNC_RND_ROUND)));
printf("float to 6 sigfigs: %s\n",
gnc_numeric_print(double_to_gnc_numeric(1.1234567890123e-5,
GNC_DENOM_AUTO,
GNC_DENOM_SIGFIGS(6) |
GNC_RND_ROUND)));
printf("add to 4 sigfigs: %s + %s = %s\n",
gnc_numeric_print(a), gnc_numeric_print(b),
gnc_numeric_print(gnc_numeric_add(a, b,
GNC_DENOM_AUTO,
GNC_DENOM_SIGFIGS(4) |
GNC_RND_ROUND)));
return 0;
}
#endif

View File

@@ -34,8 +34,9 @@ struct _gnc_numeric {
typedef struct _gnc_numeric gnc_numeric;
/* bitmasks for HOW flags */
#define GNC_NUMERIC_RND_MASK 0x0000000f
#define GNC_NUMERIC_DENOM_MASK 0x000000f0
#define GNC_NUMERIC_RND_MASK 0x0000000f
#define GNC_NUMERIC_DENOM_MASK 0x000000f0
#define GNC_NUMERIC_SIGFIGS_MASK 0x0000ff00
/* rounding/truncation modes for operations */
enum {
@@ -54,9 +55,13 @@ enum {
GNC_DENOM_EXACT = 0x10,
GNC_DENOM_REDUCE = 0x20,
GNC_DENOM_LCD = 0x30,
GNC_DENOM_FIXED = 0x40
GNC_DENOM_FIXED = 0x40,
GNC_DENOM_SIGFIG = 0x50
};
/* bits 8-15 of 'how' are reserved for the number of significant
* digits to use in the output with GNC_DENOM_SIGFIG */
/* errors */
enum {
GNC_ERROR_OK = 0,
@@ -69,6 +74,8 @@ enum {
#define GNC_DENOM_AUTO 0
#define GNC_DENOM_RECIPROCAL( a ) (- ( a ))
#define GNC_DENOM_SIGFIGS( a ) ( ((( a ) & 0xff) << 8) | GNC_DENOM_SIGFIG)
#define GNC_NUMERIC_GET_SIGFIGS( a ) ( (( a ) & 0xff00 ) >> 8)
/* make a gnc_numeric from numerator and denominator */
gnc_numeric gnc_numeric_create(gint64 num, gint64 denom);