From f76b3ad534efbe5ea42319c584e504910752bc9c Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Sun, 4 Jul 2004 03:56:40 +0000 Subject: [PATCH] fix yet another intermediate-math overflow bug. comparing two numbers gave incorrect results because intermediate calculation overflowed git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@10153 57a11ea4-9604-0410-9ed3-97b8803252fd --- src/engine/gnc-numeric.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/src/engine/gnc-numeric.c b/src/engine/gnc-numeric.c index 19e4f65e0e..fb73c57d77 100644 --- a/src/engine/gnc-numeric.c +++ b/src/engine/gnc-numeric.c @@ -216,24 +216,36 @@ gnc_numeric_positive_p(gnc_numeric a) ********************************************************************/ int -gnc_numeric_compare(gnc_numeric a, gnc_numeric b) { - gint64 ab, ba; +gnc_numeric_compare(gnc_numeric a, gnc_numeric b) +{ + gint64 aa, bb; - if(gnc_numeric_check(a) || gnc_numeric_check(b)) { + if(gnc_numeric_check(a) || gnc_numeric_check(b)) + { return 0; } - ab = a.num * b.denom; - ba = b.num * a.denom; - if(ab == ba) { - return 0; - } - else if(ab > ba) { - return 1; - } - else { + if (a.denom == b.denom) + { + if(a.num == b.num) return 0; + if(a.num > b.num) return 1; return -1; } + + if ((a.denom > 0) && (b.denom > 0)) + { + /* Avoid overflows using 128-bit intermediate math */ + qofint128 l = mult128 (a.num, b.denom); + qofint128 r = mult128 (b.num, a.denom); + return cmp128 (l,r); + } + + aa = a.num * a.denom; + bb = b.num * b.denom; + + if(aa == bb) return 0; + if(aa > bb) return 1; + return -1; }