Boost logo

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