|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r78537 - trunk/boost
From: steven_at_[hidden]
Date: 2012-05-21 22:07:35
Author: steven_watanabe
Date: 2012-05-21 22:07:33 EDT (Mon, 21 May 2012)
New Revision: 78537
URL: http://svn.boost.org/trac/boost/changeset/78537
Log:
Implement rational<IntType>/IntType operations directly to reduce calls to gcd. Patch by Mario Lang.
Text files modified:
trunk/boost/rational.hpp | 75 +++++++++++++++------------------------
1 files changed, 29 insertions(+), 46 deletions(-)
Modified: trunk/boost/rational.hpp
==============================================================================
--- trunk/boost/rational.hpp (original)
+++ trunk/boost/rational.hpp 2012-05-21 22:07:33 EDT (Mon, 21 May 2012)
@@ -21,6 +21,7 @@
// Nickolay Mladenov, for the implementation of operator+=
// Revision History
+// 05 May 12 Reduced use of implicit gcd (Mario Lang)
// 05 Nov 06 Change rational_cast to not depend on division between different
// types (Daryle Walker)
// 04 Nov 06 Off-load GCD and LCM to Boost.Math; add some invariant checks;
@@ -141,7 +142,7 @@
// Default copy constructor and assignment are fine
// Add assignment from IntType
- rational& operator=(param_type n) { return assign(n, 1); }
+ rational& operator=(param_type i) { num = i; den = 1; return *this; }
// Assign in place
rational& assign(param_type n, param_type d);
@@ -156,14 +157,14 @@
rational& operator*= (const rational& r);
rational& operator/= (const rational& r);
- rational& operator+= (param_type i);
- rational& operator-= (param_type i);
+ rational& operator+= (param_type i) { num += i * den; return *this; }
+ rational& operator-= (param_type i) { num -= i * den; return *this; }
rational& operator*= (param_type i);
rational& operator/= (param_type i);
// Increment and decrement
- const rational& operator++();
- const rational& operator--();
+ const rational& operator++() { num += den; return *this; }
+ const rational& operator--() { num -= den; return *this; }
// Operator not
bool operator!() const { return !num; }
@@ -330,46 +331,36 @@
// Mixed-mode operators
template <typename IntType>
inline rational<IntType>&
-rational<IntType>::operator+= (param_type i)
-{
- return operator+= (rational<IntType>(i));
-}
-
-template <typename IntType>
-inline rational<IntType>&
-rational<IntType>::operator-= (param_type i)
-{
- return operator-= (rational<IntType>(i));
-}
-
-template <typename IntType>
-inline rational<IntType>&
rational<IntType>::operator*= (param_type i)
{
- return operator*= (rational<IntType>(i));
+ // Avoid overflow and preserve normalization
+ IntType gcd = math::gcd(i, den);
+ num *= i / gcd;
+ den /= gcd;
+
+ return *this;
}
template <typename IntType>
-inline rational<IntType>&
+rational<IntType>&
rational<IntType>::operator/= (param_type i)
{
- return operator/= (rational<IntType>(i));
-}
+ // Avoid repeated construction
+ IntType const zero(0);
-// Increment and decrement
-template <typename IntType>
-inline const rational<IntType>& rational<IntType>::operator++()
-{
- // This can never denormalise the fraction
- num += den;
- return *this;
-}
+ if (i == zero) throw bad_rational();
+ if (num == zero) return *this;
+
+ // Avoid overflow and preserve normalization
+ IntType const gcd = math::gcd(num, i);
+ num /= gcd;
+ den *= i / gcd;
+
+ if (den < zero) {
+ num = -num;
+ den = -den;
+ }
-template <typename IntType>
-inline const rational<IntType>& rational<IntType>::operator--()
-{
- // This can never denormalise the fraction
- num -= den;
return *this;
}
@@ -477,12 +468,7 @@
template <typename IntType>
bool rational<IntType>::operator> (param_type i) const
{
- // Trap equality first
- if (num == i && den == IntType(1))
- return false;
-
- // Otherwise, we can use operator<
- return !operator<(i);
+ return operator==(i)? false: !operator<(i);
}
template <typename IntType>
@@ -597,10 +583,7 @@
template <typename IntType>
inline rational<IntType> abs(const rational<IntType>& r)
{
- if (r.numerator() >= IntType(0))
- return r;
-
- return rational<IntType>(-r.numerator(), r.denominator());
+ return r.numerator() >= IntType(0)? r: -r;
}
} // namespace boost
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk