diff options
author | Caolán McNamara <caolanm@redhat.com> | 2017-03-21 10:35:55 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2017-03-21 11:45:54 +0000 |
commit | 3ff957b0a45a1c7a2666103a6a6783e69de3446c (patch) | |
tree | 030dbb5a30a93813631aea5a2177652d20057c75 /tools | |
parent | 0a0f205775807d63e7f6dd910de368bb12b11a49 (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.cxx | 22 |
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; } |