1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
use malachite_base::num::arithmetic::traits::{DivExactAssign, Gcd};
use malachite_nz::natural::Natural;
use Rational;
impl Rational {
/// Mutates the numerator of a [`Rational`] using a provided closure, and then returns
/// whatever the closure returns.
///
/// After the closure executes, this function reduces the [`Rational`].
///
/// # Examples
/// ```
/// extern crate malachite_base;
/// extern crate malachite_nz;
///
/// use malachite_base::num::basic::traits::One;
/// use malachite_nz::natural::Natural;
/// use malachite_q::Rational;
///
/// let mut q = Rational::from_signeds(22, 7);
/// let ret = q.mutate_numerator(|x| {
/// *x -= Natural::ONE;
/// true
/// });
/// assert_eq!(q, 3);
/// assert_eq!(ret, true);
/// ```
pub fn mutate_numerator<F: FnOnce(&mut Natural) -> T, T>(&mut self, f: F) -> T {
let out = f(&mut self.numerator);
let gcd = (&self.numerator).gcd(&self.denominator);
self.numerator.div_exact_assign(&gcd);
self.denominator.div_exact_assign(gcd);
if !self.sign && self.numerator == 0 {
self.sign = true;
}
out
}
/// Mutates the denominator of a [`Rational`] using a provided closure.
///
/// After the closure executes, this function reduces the [`Rational`].
///
/// # Panics
/// Panics if the closure sets the denominator to zero.
///
/// # Examples
/// ```
/// extern crate malachite_base;
/// extern crate malachite_nz;
///
/// use malachite_base::num::basic::traits::One;
/// use malachite_nz::natural::Natural;
/// use malachite_q::Rational;
///
/// let mut q = Rational::from_signeds(22, 7);
/// let ret = q.mutate_denominator(|x| {
/// *x -= Natural::ONE;
/// true
/// });
/// assert_eq!(q.to_string(), "11/3");
/// assert_eq!(ret, true);
/// ```
pub fn mutate_denominator<F: FnOnce(&mut Natural) -> T, T>(&mut self, f: F) -> T {
let out = f(&mut self.denominator);
assert_ne!(self.denominator, 0);
let gcd = (&self.numerator).gcd(&self.denominator);
self.numerator.div_exact_assign(&gcd);
self.denominator.div_exact_assign(gcd);
out
}
/// Mutates the numerator and denominator of a [`Rational`] using a provided closure.
///
/// After the closure executes, this function reduces the [`Rational`].
///
/// # Panics
/// Panics if the closure sets the denominator to zero.
///
/// # Examples
/// ```
/// extern crate malachite_base;
/// extern crate malachite_nz;
///
/// use malachite_base::num::basic::traits::One;
/// use malachite_nz::natural::Natural;
/// use malachite_q::Rational;
///
/// let mut q = Rational::from_signeds(22, 7);
/// let ret = q.mutate_numerator_and_denominator(|x, y| {
/// *x -= Natural::ONE;
/// *y -= Natural::ONE;
/// true
/// });
/// assert_eq!(q.to_string(), "7/2");
/// assert_eq!(ret, true);
/// ```
pub fn mutate_numerator_and_denominator<F: FnOnce(&mut Natural, &mut Natural) -> T, T>(
&mut self,
f: F,
) -> T {
let out = f(&mut self.numerator, &mut self.denominator);
assert_ne!(self.denominator, 0);
let gcd = (&self.numerator).gcd(&self.denominator);
self.numerator.div_exact_assign(&gcd);
self.denominator.div_exact_assign(gcd);
if !self.sign && self.numerator == 0 {
self.sign = true;
}
out
}
}