[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