tools/source/generic/fract.cxx |   22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

New commits:
commit a7ffd469fb125f92da9848c2cfb09991862599c5
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Thu Jul 27 14:49:50 2023 +0200
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Thu Jul 27 15:49:17 2023 +0200

    Check / adjust the correct variables
    
    mnNumerator / mnDenominator are sal_Int32, so after they were assigned,
    they can't be out of range.
    
    Introduce a gcd initial step to avoid precision loss sometimes.
    
    Negative denominator is used quite some time, so drop the obsolete
    comment, while here.
    
    Change-Id: I66b77fb3d69cfd2265ac2ed88344af9cfade405b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154957
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/tools/source/generic/fract.cxx b/tools/source/generic/fract.cxx
index a583e75a7cac..abe8ee41b206 100644
--- a/tools/source/generic/fract.cxx
+++ b/tools/source/generic/fract.cxx
@@ -55,21 +55,25 @@ static constexpr bool isOutOfRange(sal_Int64 nNum)
             || nNum > std::numeric_limits<sal_Int32>::max();
 }
 
-// Initialized by setting nNum as nominator and nDen as denominator
-// Negative values in the denominator are invalid and cause the
-// inversion of both nominator and denominator signs
-// in order to return the correct value.
 Fraction::Fraction( sal_Int64 nNum, sal_Int64 nDen ) : mnNumerator(nNum), 
mnDenominator(nDen)
 {
     if ( isOutOfRange(nNum) || isOutOfRange(nDen) )
     {
         // tdf#143200
-        SAL_WARN("tools.fraction", "values outside of range we can represent, 
doing reduction, which will reduce precision");
-        do
+        if (const auto gcd = std::gcd(nNum, nDen); gcd > 1)
         {
-            mnNumerator /= 2;
-            mnDenominator /= 2;
-        } while (isOutOfRange(mnNumerator) || isOutOfRange(mnDenominator));
+            nNum /= gcd;
+            nDen /= gcd;
+        }
+        SAL_WARN_IF(isOutOfRange(nNum) || isOutOfRange(nDen),
+                    "tools.fraction", "values outside of range we can 
represent, doing reduction, which will reduce precision");
+        while (isOutOfRange(nNum) || isOutOfRange(nDen))
+        {
+            nNum /= 2;
+            nDen /= 2;
+        }
+        mnNumerator = nNum;
+        mnDenominator = nDen;
     }
     if ( mnDenominator == 0 )
     {

Reply via email to