[Gnucash-changes] fix what I beleive is the last of the overflow
bugs.
Linas Vepstas
linas at cvs.gnucash.org
Fri Jul 2 21:19:51 EDT 2004
Log Message:
-----------
fix what I beleive is the last of the overflow bugs.
If rounding is allowed, then multiplication should (never?) overflow.
Modified Files:
--------------
gnucash/src/engine:
gnc-numeric.c
Revision Data
-------------
Index: gnc-numeric.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/engine/gnc-numeric.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -Lsrc/engine/gnc-numeric.c -Lsrc/engine/gnc-numeric.c -u -r1.50 -r1.51
--- src/engine/gnc-numeric.c
+++ src/engine/gnc-numeric.c
@@ -460,10 +460,30 @@
/* If it looks to be overflowing, try to reduce the fraction ... */
if (bigprod.isbig)
{
- product = reduce128 (bigprod, product.denom);
- if (gnc_numeric_check (product))
+ /* 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)
{
- return gnc_numeric_error (GNC_ERROR_OVERFLOW);
+ product = reduce128 (bigprod, product.denom);
+ if (gnc_numeric_check (product))
+ {
+ 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);
+ }
}
}
@@ -584,11 +604,10 @@
}
else
{
- /* If not exact/fixed, and rounding allowed, then
- * shift until there's no more overflow. The conversion
- * at the end will fix things up the final value. */
- if (((how & GNC_NUMERIC_RND_MASK) == GNC_HOW_RND_NEVER) ||
- ((how & GNC_NUMERIC_DENOM_MASK) == GNC_HOW_DENOM_EXACT))
+ /* 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)
{
return gnc_numeric_error (GNC_ERROR_OVERFLOW);
}
@@ -599,6 +618,10 @@
}
quotient.num = sgn * rnume.lo;
quotient.denom = rdeno.lo;
+ if (0 == quotient.denom)
+ {
+ return gnc_numeric_error (GNC_ERROR_OVERFLOW);
+ }
}
}
}
More information about the gnucash-changes
mailing list