summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2017-03-21 10:35:55 +0000
committerCaolán McNamara <caolanm@redhat.com>2017-03-21 11:45:54 +0000
commit3ff957b0a45a1c7a2666103a6a6783e69de3446c (patch)
tree030dbb5a30a93813631aea5a2177652d20057c75 /tools
parent0a0f205775807d63e7f6dd910de368bb12b11a49 (diff)
duplicate rational::operator*= into tools
for modification, no logic changed intended in this step Change-Id: Ib41051a83bc9e37677d765e51e9f56cede0efb3e
Diffstat (limited to 'tools')
-rw-r--r--tools/source/generic/fract.cxx22
1 files changed, 20 insertions, 2 deletions
diff --git a/tools/source/generic/fract.cxx b/tools/source/generic/fract.cxx
index c79b24bbf3a3..068a2b6429a8 100644
--- a/tools/source/generic/fract.cxx
+++ b/tools/source/generic/fract.cxx
@@ -170,6 +170,24 @@ Fraction& Fraction::operator -= ( const Fraction& rVal )
return *this;
}
+namespace
+{
+ template<typename T> void multiply_by(boost::rational<T>& i, const boost::rational<T>& r)
+ {
+ // Protect against self-modification
+ T num = r.numerator();
+ T den = r.denominator();
+
+ // Avoid overflow and preserve normalization
+ T gcd1 = boost::integer::gcd(i.numerator(), den);
+ T gcd2 = boost::integer::gcd(num, i.denominator());
+ num = (i.numerator() / gcd1) * (num / gcd2);
+ den = (i.denominator() / gcd2) * (den / gcd1);
+
+ i.assign(num, den);
+ }
+}
+
Fraction& Fraction::operator *= ( const Fraction& rVal )
{
if ( !rVal.mpImpl->valid )
@@ -181,9 +199,9 @@ Fraction& Fraction::operator *= ( const Fraction& rVal )
return *this;
}
- mpImpl->value *= rVal.mpImpl->value;
+ multiply_by(mpImpl->value, rVal.mpImpl->value);
- if ( HasOverflowValue() )
+ if (HasOverflowValue())
{
mpImpl->valid = false;
}