     }
     return (y, overflow)
   }
-
+  
   /// Compute the least common multiplier of `x` and `y`.
   public static func lcmWithOverflow(_ x: T, _ y: T) -> (T, Bool) {
     let (abs, overflow1) = x.multipliedReportingOverflow(by: y)
     let (gcd, overflow2) = Rational.gcdWithOverflow(x, y)
     return ((abs < 0 ? -abs : abs) / gcd, overflow1 || overflow2)
   }
-
-  /// Returns the greatest common denominator for the two given rational numbers and a boolean
-  /// which indicates whether there was an overflow.
-  public static func gcdWithOverflow(_ x: Rational<T>, _ y: Rational<T>) -> (Rational<T>, Bool) {
-    let (numer, overflow1) = Rational.gcdWithOverflow(x.numerator, y.numerator)
-    let (denom, overflow2) = Rational.lcmWithOverflow(x.denominator, y.denominator)
+  
+  /// Add `self` and `rhs` and return a tuple consisting of the result and a boolean which
+  /// indicates whether there was an overflow.
+  public func addingReportingOverflow(_ rhs: Rational<T>)
+                                  -> (partialValue: Rational<T>, overflow: Bool) {
+    let (n1, n2, denom, overflow1) = Rational.commonDenomWithOverflow(self, rhs)
+    let (numer, overflow2) = n1.addingReportingOverflow(n2)
+    let (res, overflow3) = Rational.rationalWithOverflow(numer, denom)
+    return (res, overflow1 || overflow2 || overflow3)
+  }
+  
+  /// Subtract `rhs` from `self` and return a tuple consisting of the result and a boolean which
+  /// indicates whether there was an overflow.
+  public func subtractingReportingOverflow(_ rhs: Rational<T>)
+                                       -> (partialValue: Rational<T>, overflow: Bool) {
+    let (n1, n2, denom, overflow1) = Rational.commonDenomWithOverflow(self, rhs)
+    let (numer, overflow2) = n1.subtractingReportingOverflow(n2)
+    let (res, overflow3) = Rational.rationalWithOverflow(numer, denom)
+    return (res, overflow1 || overflow2 || overflow3)
+  }
+  
+  /// Multiply `self` and `rhs` and return a tuple consisting of the result and a boolean which
+  /// indicates whether there was an overflow.
+  public func multipliedReportingOverflow(by rhs: Rational<T>)
+                                      -> (partialValue: Rational<T>, overflow: Bool) {
+    let (numer, overflow1) = self.numerator.multipliedReportingOverflow(by: rhs.numerator)
+    let (denom, overflow2) = self.denominator.multipliedReportingOverflow(by: rhs.denominator)
+    let (res, overflow3) = Rational.rationalWithOverflow(numer, denom)
+    return (res, overflow1 || overflow2 || overflow3)
+  }
+
+  /// Divide `lhs` by `rhs` and return a tuple consisting of the result and a boolean which
+  /// indicates whether there was an overflow.
+  public func dividedReportingOverflow(by rhs: Rational<T>)
+                                   -> (partialValue: Rational<T>, overflow: Bool) {
+    let (numer, overflow1) = self.numerator.multipliedReportingOverflow(by: rhs.denominator)
+    let (denom, overflow2) = self.denominator.multipliedReportingOverflow(by: rhs.numerator)
+    let (res, overflow3) = Rational.rationalWithOverflow(numer, denom)
+    return (res, overflow1 || overflow2 || overflow3)
+  }
+  
+  /// Returns the greatest common denominator for `self` and `y` and a boolean which indicates
+  /// whether there was an overflow.
+  public func gcdReportingOverflow(with y: Rational<T>)
+                               -> (partialValue: Rational<T>, overflow: Bool) {
+    let (numer, overflow1) = Rational.gcdWithOverflow(self.numerator, y.numerator)
+    let (denom, overflow2) = Rational.lcmWithOverflow(self.denominator, y.denominator)
     return (Rational(numer, denom), overflow1 || overflow2)
   }
-
-  /// Returns the least common multiplier for the two given rational numbers and a boolean
-  /// which indicates whether there was an overflow.
-  public static func lcmWithOverflow(_ x: Rational<T>, _ y: Rational<T>) -> (Rational<T>, Bool) {
-    let (xn, yn, denom, overflow1) = Rational.commonDenomWithOverflow(x, y)
+  
+  /// Returns the least common multiplier for `self` and `y` and a boolean which indicates
+  /// whether there was an overflow.
+  public func lcmReportingOverflow(with y: Rational<T>)
+                               -> (partialValue: Rational<T>, overflow: Bool) {
+    let (xn, yn, denom, overflow1) = Rational.commonDenomWithOverflow(self, y)
     let (numer, overflow2) = Rational.lcmWithOverflow(xn, yn)
     return (Rational(numer, denom), overflow1 || overflow2)
   }


  /// Raises this rational value to the power of `exp`.
  func toPower(of exp: Integer) -> Self
}

// TODO: make this a static member of `Rational` once this is supported
private let rationalSeparator: Character = "/"


/// Struct `Rational<T>` implements the `RationalNumber` interface on top of the

  return lhs.compare(to: rhs) != 0
}

// TODO: make this a static member of `Rational` once this is supported
private let rationalSeparator: Character = "/"
