use crate::Rational;
use crate::conversion::traits::ContinuedFraction;
use core::mem::swap;
use malachite_base::num::arithmetic::traits::{DivMod, Floor};
use malachite_nz::integer::Integer;
use malachite_nz::natural::Natural;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct RationalContinuedFraction {
numerator: Natural,
denominator: Natural,
}
impl RationalContinuedFraction {
pub_crate_test! {is_done(&self) -> bool {
self.denominator == 0u32 || self.numerator == 0u32
}}
}
impl Iterator for RationalContinuedFraction {
type Item = Natural;
fn next(&mut self) -> Option<Natural> {
if self.denominator == 0u32 || self.numerator == 0u32 {
None
} else {
let n;
(n, self.numerator) = (&self.numerator).div_mod(&self.denominator);
swap(&mut self.numerator, &mut self.denominator);
Some(n)
}
}
}
impl ContinuedFraction for Rational {
type CF = RationalContinuedFraction;
fn continued_fraction(mut self) -> (Integer, RationalContinuedFraction) {
let f = (&self).floor();
self -= Self::from(&f);
let (d, n) = self.into_numerator_and_denominator();
(
f,
RationalContinuedFraction {
numerator: n,
denominator: d,
},
)
}
}
impl ContinuedFraction for &Rational {
type CF = RationalContinuedFraction;
fn continued_fraction(self) -> (Integer, RationalContinuedFraction) {
let f = self.floor();
let (d, n) = (self - Rational::from(&f)).into_numerator_and_denominator();
(
f,
RationalContinuedFraction {
numerator: n,
denominator: d,
},
)
}
}