[Gnucash-changes] remove 32-bit limits that show up in division
calculations (could cause
Linas Vepstas
linas at cvs.gnucash.org
Sat Jun 26 12:16:56 EDT 2004
Log Message:
-----------
remove 32-bit limits that show up in division calculations
(could cause overflow during certain pricing calculations)
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.39
retrieving revision 1.40
diff -Lsrc/engine/gnc-numeric.c -Lsrc/engine/gnc-numeric.c -u -r1.39 -r1.40
--- src/engine/gnc-numeric.c
+++ src/engine/gnc-numeric.c
@@ -146,16 +146,14 @@
quotient.lo = lo + n.lo/d;
/* Deal with low remainder bits.
- * There's probably a more efficient way of doing this.
- * XXX This algo breaks if the value of teh denominator
- * is larger than 2 billion.
+ * Is there a more efficient way of doing this?
*/
- guint64 rnd = quotient.lo;
- rnd *= d;
- rnd &= 0x7fffffff;
- rnd = (n.lo & 0x7fffffff) - rnd;
- rnd &= 0x7fffffff;
- rnd /= d;
+ gncint128 mu = mult128 (quotient.lo, d);
+
+ gint64 nn = 0x7fffffffffffffffULL & n.lo;
+ gint64 rr = 0x7fffffffffffffffULL & mu.lo;
+ gint64 rnd = nn - rr;
+ rnd /= d;
/* ?? will this ever overflow ? */
qlo = quotient.lo;
@@ -171,21 +169,20 @@
return quotient;
}
-/** Return the remainder of a signed 128-bit number modulo a signed 64-bit,
- * XXX the current algo only works for divisor values less than 1<<31
- * (2 billion)
+/** Return the remainder of a signed 128-bit number modulo
+ * a signed 64-bit. I beleive that ths algo is overflow-free,
+ * but should be audited some more ...
*/
static inline gint64
rem128 (gncint128 n, gint64 d)
{
gncint128 quotient = div128 (n,d);
- guint64 rnd = quotient.lo;
- rnd *= d;
- rnd &= 0x7fffffff;
- rnd = (n.lo & 0x7fffffff) - rnd;
- rnd &= 0x7fffffff;
- return rnd;
+ gncint128 mu = mult128 (quotient.lo, d);
+
+ gint64 nn = 0x7fffffffffffffffULL & n.lo;
+ gint64 rr = 0x7fffffffffffffffULL & mu.lo;
+ return nn - rr;
}
/** Return the ratio n/d reduced so that there are no common factors. */
More information about the gnucash-changes
mailing list