summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorMike Kaganski <mike.kaganski@collabora.com>2023-07-27 14:49:50 +0200
committerMike Kaganski <mike.kaganski@collabora.com>2023-07-27 15:49:17 +0200
commita7ffd469fb125f92da9848c2cfb09991862599c5 (patch)
tree4ccfd36ce5f2445d27129093cff0a57819f9b6b6 /tools
parent89ccdd1b7be48461a33200c43b2fd340e646df8b (diff)
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.kaganski@collabora.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/source/generic/fract.cxx22
1 files changed, 13 insertions, 9 deletions
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 )
{