* src/engine/gnc-numeric.c -- be more intelligent when operating

on numbers of different denominators.  In particular, convert
	  both numbers to the lcd and then operate on them, instead of
	  assuming that a "cross-multiply" is safe.
	* src/app-utils/test/test-print-parse-amount.c -- add more tests for
	  PrintAmountInternal by checking force_fit and round.  Excercises
	  a bug (fixed in this patch) where cross-multiplies were NOT safe.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@7848 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Derek Atkins
2003-01-19 19:38:14 +00:00
parent 9de4ec1b86
commit 1e8397b194
3 changed files with 44 additions and 9 deletions

View File

@@ -1,3 +1,13 @@
2003-01-19 Derek Atkins <derek@ihtfp.com>
* src/engine/gnc-numeric.c -- be more intelligent when operating
on numbers of different denominators. In particular, convert
both numbers to the lcd and then operate on them, instead of
assuming that a "cross-multiply" is safe.
* src/app-utils/test/test-print-parse-amount.c -- add more tests for
PrintAmountInternal by checking force_fit and round. Excercises
a bug (fixed in this patch) where cross-multiplies were NOT safe.
2003-01-18 Derek Atkins <derek@ihtfp.com>
* src/business/business-core/gncTaxTable.[ch]: add functions to

View File

@@ -40,8 +40,6 @@ test_num (gnc_numeric n)
print_info.min_decimal_places = 0;
print_info.use_locale = 1;
print_info.use_symbol = 0;
print_info.force_fit = 0;
print_info.round = 0;
for (i = 1, fraction = 10; i < 9; i++, fraction *= 10)
{
@@ -50,16 +48,28 @@ test_num (gnc_numeric n)
print_info.use_separators = 1;
print_info.monetary = 1;
print_info.max_decimal_places = i;
print_info.force_fit = 0;
print_info.round = 0;
n1 = gnc_numeric_convert (n, fraction, GNC_RND_ROUND);
test_num_print_info (n1, print_info);
print_info.monetary = 0;
test_num_print_info (n1, print_info);
print_info.use_separators = 0;
test_num_print_info (n1, print_info);
print_info.round = 1;
test_num_print_info (n1, print_info);
print_info.round = 0;
print_info.force_fit = 1;
test_num_print_info (n1, print_info);
print_info.round = 1;
test_num_print_info (n1, print_info);
}
}

View File

@@ -191,6 +191,7 @@ gnc_numeric
gnc_numeric_add(gnc_numeric a, gnc_numeric b,
gint64 denom, gint how) {
gnc_numeric sum;
gint64 lcd;
if(gnc_numeric_check(a) || gnc_numeric_check(b)) {
return gnc_numeric_error(GNC_ERROR_ARG);
@@ -228,8 +229,12 @@ gnc_numeric_add(gnc_numeric a, gnc_numeric b,
sum.denom = a.denom;
}
else {
sum.num = a.num*b.denom + b.num*a.denom;
sum.denom = a.denom*b.denom;
/* ok, convert to the lcd and compute from there... */
lcd = gnc_numeric_lcd(a,b);
sum.num = a.num*(lcd/a.denom) + b.num*(lcd/b.denom);
sum.denom = lcd;
// sum.num = a.num*b.denom + b.num*a.denom;
// sum.denom = a.denom*b.denom;
}
if((denom == GNC_DENOM_AUTO) &&
@@ -261,6 +266,7 @@ gnc_numeric
gnc_numeric_sub(gnc_numeric a, gnc_numeric b,
gint64 denom, gint how) {
gnc_numeric diff;
gint64 lcd;
if(gnc_numeric_check(a) || gnc_numeric_check(b)) {
return gnc_numeric_error(GNC_ERROR_ARG);
@@ -298,8 +304,12 @@ gnc_numeric_sub(gnc_numeric a, gnc_numeric b,
diff.denom = a.denom;
}
else {
diff.num = a.num*b.denom - b.num*a.denom;
diff.denom = a.denom*b.denom;
/* ok, convert to the lcd and compute from there... */
lcd = gnc_numeric_lcd(a,b);
diff.num = a.num*(lcd/a.denom) - b.num*(lcd/b.denom);
diff.denom = lcd;
// diff.num = a.num*b.denom - b.num*a.denom;
// diff.denom = a.denom*b.denom;
}
if((denom == GNC_DENOM_AUTO) &&
@@ -387,6 +397,7 @@ gnc_numeric
gnc_numeric_div(gnc_numeric a, gnc_numeric b,
gint64 denom, gint how) {
gnc_numeric quotient;
gint64 lcd;
if(gnc_numeric_check(a) || gnc_numeric_check(b)) {
return gnc_numeric_error(GNC_ERROR_ARG);
@@ -421,8 +432,12 @@ gnc_numeric_div(gnc_numeric a, gnc_numeric b,
quotient.denom = b.num;
}
else {
quotient.num = a.num*b.denom;
quotient.denom = a.denom*b.num;
/* ok, convert to the lcd and compute from there... */
lcd = gnc_numeric_lcd(a,b);
quotient.num = a.num*(lcd/a.denom);
quotient.denom = b.num*(lcd/b.denom);
// quotient.num = a.num*b.denom;
// quotient.denom = a.denom*b.num;
}
if(quotient.denom < 0) {