diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2023-07-27 14:49:50 +0200 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2023-07-27 15:49:17 +0200 |
commit | a7ffd469fb125f92da9848c2cfb09991862599c5 (patch) | |
tree | 4ccfd36ce5f2445d27129093cff0a57819f9b6b6 /tools/source | |
parent | 89ccdd1b7be48461a33200c43b2fd340e646df8b (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/source')
-rw-r--r-- | tools/source/generic/fract.cxx | 22 |
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 ) { |