mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
@@ -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);
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user