fix what I beleive is the last of the overflow bugs.

If rounding is allowed, then multiplication should (never?) overflow.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@10135 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
Linas Vepstas 2004-07-03 01:19:51 +00:00
parent 7c48896b8d
commit 0a68dbc6d8

View File

@ -459,6 +459,11 @@ gnc_numeric_mul(gnc_numeric a, gnc_numeric b,
/* If it looks to be overflowing, try to reduce the fraction ... */ /* If it looks to be overflowing, try to reduce the fraction ... */
if (bigprod.isbig) if (bigprod.isbig)
{
/* If rounding allowed, then shift until there's no
* more overflow. The conversion at the end will fix
* things up for the final value. */
if ((how & GNC_NUMERIC_RND_MASK) == GNC_HOW_RND_NEVER)
{ {
product = reduce128 (bigprod, product.denom); product = reduce128 (bigprod, product.denom);
if (gnc_numeric_check (product)) if (gnc_numeric_check (product))
@ -466,6 +471,21 @@ gnc_numeric_mul(gnc_numeric a, gnc_numeric b,
return gnc_numeric_error (GNC_ERROR_OVERFLOW); return gnc_numeric_error (GNC_ERROR_OVERFLOW);
} }
} }
else
{
while (bigprod.isbig)
{
bigprod = shift128 (bigprod);
product.denom >>= 1;
}
product.num = bigprod.lo;
if (bigprod.isneg) product.num = -product.num;
if (0 == product.denom)
{
return gnc_numeric_error (GNC_ERROR_OVERFLOW);
}
}
}
#if 0 /* currently, product denom won't ever be zero */ #if 0 /* currently, product denom won't ever be zero */
if(product.denom < 0) { if(product.denom < 0) {
@ -584,11 +604,10 @@ gnc_numeric_div(gnc_numeric a, gnc_numeric b,
} }
else else
{ {
/* If not exact/fixed, and rounding allowed, then /* If rounding allowed, then shift until there's no
* shift until there's no more overflow. The conversion * more overflow. The conversion at the end will fix
* at the end will fix things up the final value. */ * things up for the final value. */
if (((how & GNC_NUMERIC_RND_MASK) == GNC_HOW_RND_NEVER) || if ((how & GNC_NUMERIC_RND_MASK) == GNC_HOW_RND_NEVER)
((how & GNC_NUMERIC_DENOM_MASK) == GNC_HOW_DENOM_EXACT))
{ {
return gnc_numeric_error (GNC_ERROR_OVERFLOW); return gnc_numeric_error (GNC_ERROR_OVERFLOW);
} }
@ -599,6 +618,10 @@ gnc_numeric_div(gnc_numeric a, gnc_numeric b,
} }
quotient.num = sgn * rnume.lo; quotient.num = sgn * rnume.lo;
quotient.denom = rdeno.lo; quotient.denom = rdeno.lo;
if (0 == quotient.denom)
{
return gnc_numeric_error (GNC_ERROR_OVERFLOW);
}
} }
} }
} }