summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorNoel Grandin <noel.grandin@collabora.co.uk>2022-10-27 08:48:25 +0200
committerNoel Grandin <noel.grandin@collabora.co.uk>2022-10-27 10:58:04 +0200
commit551e5943d4bec10c31077f38ccf5d8149c05265c (patch)
treeb987153b2cb1b09f2d33cd774bd7ffd6878354d3 /tools
parentab83d7d57d0fae106037b12651adb397b48354e4 (diff)
tdf#123419 optimise ImplMakeFraction
which is very hot here. Push it down into Fraction, where we can skip the construction of boost::rational intermediate values Change-Id: I7e5f18456a252a159d3a50e9297168e5ba9e1588 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141894 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Diffstat (limited to 'tools')
-rw-r--r--tools/source/generic/fract.cxx40
1 files changed, 40 insertions, 0 deletions
diff --git a/tools/source/generic/fract.cxx b/tools/source/generic/fract.cxx
index 7f2ffba1003d..b6ae743764df 100644
--- a/tools/source/generic/fract.cxx
+++ b/tools/source/generic/fract.cxx
@@ -483,4 +483,44 @@ size_t Fraction::GetHashValue() const
return hash;
}
+Fraction Fraction::MakeFraction( tools::Long nN1, tools::Long nN2, tools::Long nD1, tools::Long nD2 )
+{
+ if( nD1 == 0 || nD2 == 0 ) //under these bad circumstances the following while loop will be endless
+ {
+ SAL_WARN("tools.fraction", "Invalid parameter for ImplMakeFraction");
+ return Fraction( 1, 1 );
+ }
+
+ tools::Long i = 1;
+
+ if ( nN1 < 0 ) { i = -i; nN1 = -nN1; }
+ if ( nN2 < 0 ) { i = -i; nN2 = -nN2; }
+ if ( nD1 < 0 ) { i = -i; nD1 = -nD1; }
+ if ( nD2 < 0 ) { i = -i; nD2 = -nD2; }
+ // all positive; i sign
+
+ boost::rational<sal_Int32> a = toRational(i*nN1, nD1);
+ boost::rational<sal_Int32> b = toRational(nN2, nD2);
+ bool bFail = checked_multiply_by(a, b);
+
+
+ while ( bFail ) {
+ if ( nN1 > nN2 )
+ nN1 = (nN1 + 1) / 2;
+ else
+ nN2 = (nN2 + 1) / 2;
+ if ( nD1 > nD2 )
+ nD1 = (nD1 + 1) / 2;
+ else
+ nD2 = (nD2 + 1) / 2;
+
+ a = toRational(i*nN1, nD1);
+ b = toRational(nN2, nD2);
+ bFail = checked_multiply_by(a, b);
+ }
+
+ rational_ReduceInaccurate(a, /*nSignificantBits*/32);
+ return Fraction(a.numerator(), a.denominator());
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */