gnucash stable: Bug 797384 - Gnucash doesn't handle commodity prices with big...

John Ralls jralls at code.gnucash.org
Mon May 25 14:32:42 EDT 2026


Updated	 via  https://github.com/Gnucash/gnucash/commit/2911a0cc (commit)
	from  https://github.com/Gnucash/gnucash/commit/88e50537 (commit)



commit 2911a0cce3e5816ae1f4f5ef6a7ca3f7cdea3135
Author: John Ralls <jralls at ceridwen.us>
Date:   Mon May 25 11:23:38 2026 -0700

    Bug 797384 - Gnucash doesn't handle commodity prices with big...
    
    numerator/denominator properly
    
    - Use GNC_HOW_DENOM_REDUCE | GNC_HOW_RND_ROUND to preserve precision while
    avoiding overflows.
    
    - Rearrange the function's tests to perform only one division or
    multiplication instead of unconditionally dividing
    
    - Rename the from_ and to_ variables to p(rice)1 and p2 to reduce
    conflation with the input from and to.

diff --git a/libgnucash/engine/gnc-pricedb.cpp b/libgnucash/engine/gnc-pricedb.cpp
index 66946358cb..4a5764368b 100644
--- a/libgnucash/engine/gnc-pricedb.cpp
+++ b/libgnucash/engine/gnc-pricedb.cpp
@@ -30,6 +30,7 @@
 #include <stdlib.h>
 #include "gnc-date.h"
 #include "gnc-datetime.hpp"
+#include "gnc-numeric.h"
 #include "gnc-pricedb-p.h"
 #include <qofinstance-p.h>
 
@@ -2371,33 +2372,34 @@ extract_common_prices (PriceList *from_prices, PriceList *to_prices,
     return retval;
 }
 
-
 static gnc_numeric
 convert_price (const gnc_commodity *from, const gnc_commodity *to, PriceTuple tuple)
 {
-    gnc_commodity *from_com = gnc_price_get_commodity (tuple.from);
-    gnc_commodity *from_cur = gnc_price_get_currency (tuple.from);
-    gnc_commodity *to_com = gnc_price_get_commodity (tuple.to);
-    gnc_commodity *to_cur = gnc_price_get_currency (tuple.to);
-    gnc_numeric from_val = gnc_price_get_value (tuple.from);
-    gnc_numeric to_val = gnc_price_get_value (tuple.to);
-    gnc_numeric price;
-    int no_round = GNC_HOW_DENOM_EXACT | GNC_HOW_RND_NEVER;
-
-    price = gnc_numeric_div (to_val, from_val, GNC_DENOM_AUTO, no_round);
+    gnc_commodity *p1_com = gnc_price_get_commodity (tuple.from);
+    gnc_commodity *p1_cur = gnc_price_get_currency (tuple.from);
+    gnc_commodity *p2_com = gnc_price_get_commodity (tuple.to);
+    gnc_commodity *p2_cur = gnc_price_get_currency (tuple.to);
+    gnc_numeric p1_val = gnc_price_get_value (tuple.from);
+    gnc_numeric p2_val = gnc_price_get_value (tuple.to);
 
     gnc_price_unref (tuple.from);
     gnc_price_unref (tuple.to);
 
-    if (from_cur == from && to_cur == to)
-        return price;
+    if ((p1_com == from && p2_com == to) ||
+        (p1_cur == from && p2_cur == to))
+    {
+        auto price = gnc_numeric_div (p2_val, p1_val, GNC_DENOM_AUTO,
+                                      GNC_HOW_DENOM_REDUCE | GNC_HOW_RND_ROUND);
 
-    if (from_com == from && to_com == to)
-        return gnc_numeric_invert (price);
+        if (p1_cur == from)
+            return price;
 
-    price = gnc_numeric_mul (from_val, to_val, GNC_DENOM_AUTO, no_round);
+        return gnc_numeric_invert (price);
+    }
 
-    if (from_cur == from)
+    auto price = gnc_numeric_mul (p1_val, p2_val, GNC_DENOM_AUTO,
+                                  GNC_HOW_DENOM_REDUCE | GNC_HOW_RND_ROUND);
+    if (p1_cur == from)
         return gnc_numeric_invert (price);
 
     return price;



Summary of changes:
 libgnucash/engine/gnc-pricedb.cpp | 36 +++++++++++++++++++-----------------
 1 file changed, 19 insertions(+), 17 deletions(-)



More information about the gnucash-changes mailing list