rithm/fraction/
add_assign.rs

1use std::ops::{Add, AddAssign, Mul};
2
3use crate::big_int::BigInt;
4
5use super::types::{Fraction, NormalizeModuli};
6
7impl<Digit, const DIGIT_BITNESS: usize> AddAssign
8    for Fraction<BigInt<Digit, DIGIT_BITNESS>>
9where
10    for<'a> BigInt<Digit, DIGIT_BITNESS>: Add<Output = BigInt<Digit, DIGIT_BITNESS>>
11        + NormalizeModuli<
12            Output = (
13                BigInt<Digit, DIGIT_BITNESS>,
14                BigInt<Digit, DIGIT_BITNESS>,
15            ),
16        >,
17    for<'a> &'a BigInt<Digit, DIGIT_BITNESS>: Mul<Output = BigInt<Digit, DIGIT_BITNESS>>
18        + Mul<
19            BigInt<Digit, DIGIT_BITNESS>,
20            Output = BigInt<Digit, DIGIT_BITNESS>,
21        >,
22{
23    fn add_assign(&mut self, other: Self) {
24        (self.numerator, self.denominator) = (&self.numerator
25            * &other.denominator
26            + &self.denominator * other.numerator)
27            .normalize_moduli(&self.denominator * other.denominator);
28    }
29}
30
31impl<Digit, const DIGIT_BITNESS: usize> AddAssign<&Self>
32    for Fraction<BigInt<Digit, DIGIT_BITNESS>>
33where
34    for<'a> BigInt<Digit, DIGIT_BITNESS>: Add<Output = BigInt<Digit, DIGIT_BITNESS>>
35        + NormalizeModuli<
36            Output = (
37                BigInt<Digit, DIGIT_BITNESS>,
38                BigInt<Digit, DIGIT_BITNESS>,
39            ),
40        >,
41    for<'a> &'a BigInt<Digit, DIGIT_BITNESS>:
42        Mul<Output = BigInt<Digit, DIGIT_BITNESS>>,
43{
44    fn add_assign(&mut self, other: &Self) {
45        (self.numerator, self.denominator) = (&self.numerator
46            * &other.denominator
47            + &self.denominator * &other.numerator)
48            .normalize_moduli(&self.denominator * &other.denominator);
49    }
50}
51
52impl<Digit, const DIGIT_BITNESS: usize> AddAssign<BigInt<Digit, DIGIT_BITNESS>>
53    for Fraction<BigInt<Digit, DIGIT_BITNESS>>
54where
55    for<'a> BigInt<Digit, DIGIT_BITNESS>: NormalizeModuli<
56        &'a BigInt<Digit, DIGIT_BITNESS>,
57        Output = (BigInt<Digit, DIGIT_BITNESS>, BigInt<Digit, DIGIT_BITNESS>),
58    >,
59    for<'a> &'a BigInt<Digit, DIGIT_BITNESS>: Add<
60            BigInt<Digit, DIGIT_BITNESS>,
61            Output = BigInt<Digit, DIGIT_BITNESS>,
62        > + Mul<
63            BigInt<Digit, DIGIT_BITNESS>,
64            Output = BigInt<Digit, DIGIT_BITNESS>,
65        >,
66{
67    fn add_assign(&mut self, other: BigInt<Digit, DIGIT_BITNESS>) {
68        (self.numerator, self.denominator) = (&self.numerator
69            + &self.denominator * other)
70            .normalize_moduli(&self.denominator);
71    }
72}
73
74impl<Digit, const DIGIT_BITNESS: usize>
75    AddAssign<&BigInt<Digit, DIGIT_BITNESS>>
76    for Fraction<BigInt<Digit, DIGIT_BITNESS>>
77where
78    for<'a> BigInt<Digit, DIGIT_BITNESS>: NormalizeModuli<
79        &'a BigInt<Digit, DIGIT_BITNESS>,
80        Output = (BigInt<Digit, DIGIT_BITNESS>, BigInt<Digit, DIGIT_BITNESS>),
81    >,
82    for<'a> &'a BigInt<Digit, DIGIT_BITNESS>: Add<
83            BigInt<Digit, DIGIT_BITNESS>,
84            Output = BigInt<Digit, DIGIT_BITNESS>,
85        > + Mul<Output = BigInt<Digit, DIGIT_BITNESS>>,
86{
87    fn add_assign(&mut self, other: &BigInt<Digit, DIGIT_BITNESS>) {
88        (self.numerator, self.denominator) = (&self.numerator
89            + &self.denominator * other)
90            .normalize_moduli(&self.denominator);
91    }
92}
93
94macro_rules! integer_fraction_add_assign_impl {
95    ($($integer:ty)*) => ($(
96        impl AddAssign for Fraction<$integer> {
97            fn add_assign(&mut self, other: Self) {
98                (self.numerator, self.denominator) = (self.numerator
99                    * other.denominator
100                    + self.denominator * other.numerator)
101                    .normalize_moduli(self.denominator * other.denominator);
102            }
103        }
104
105        impl AddAssign<$integer> for Fraction<$integer> {
106            fn add_assign(&mut self, other: $integer) {
107                (self.numerator, self.denominator) = (self.numerator
108                    + self.denominator * other)
109                    .normalize_moduli(self.denominator);
110            }
111        }
112    )*)
113}
114
115integer_fraction_add_assign_impl!(
116    i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize
117);