Skip to main content

relp_num/rational/small/ops/
with_one.rs

1use std::cmp::Ordering;
2use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign};
3
4use num_traits::Zero;
5
6use crate::{Rational128, Rational16, Rational32, Rational64, Rational8, Sign};
7use crate::fixed::One;
8
9macro_rules! impls {
10    ($name:ty) => {
11        impl From<One> for $name {
12            #[inline]
13            fn from(_: One) -> Self {
14                num_traits::One::one()
15            }
16        }
17
18        impl From<&One> for $name {
19            #[inline]
20            fn from(_: &One) -> Self {
21                num_traits::One::one()
22            }
23        }
24
25        impl Add<One> for $name {
26            type Output = Self;
27
28            #[inline]
29            fn add(mut self, _: One) -> Self::Output {
30                AddAssign::add_assign(&mut self, One);
31                self
32            }
33        }
34
35        impl Add<&One> for $name {
36            type Output = Self;
37
38            #[inline]
39            fn add(mut self, _: &One) -> Self::Output {
40                AddAssign::add_assign(&mut self, &One);
41                self
42            }
43        }
44
45        impl AddAssign<One> for $name {
46            #[inline]
47            fn add_assign(&mut self, _: One) {
48                AddAssign::add_assign(self, &One);
49            }
50        }
51
52        impl AddAssign<&One> for $name {
53            #[inline]
54            fn add_assign(&mut self, _: &One) {
55                match self.sign {
56                    Sign::Positive => self.numerator += self.denominator,
57                    Sign::Zero => {
58                        self.sign = Sign::Positive;
59                        debug_assert!(self.numerator.is_zero());
60                        num_traits::One::set_one(&mut self.numerator);
61                        debug_assert!(num_traits::One::is_one(&self.denominator));
62                    }
63                    Sign::Negative => {
64                        if self.numerator != 1 || self.denominator != 1 {
65                            match self.numerator.cmp(&self.denominator) {
66                                Ordering::Less => {
67                                    self.numerator = self.denominator - self.numerator;
68                                    self.sign = Sign::Positive;
69                                }
70                                Ordering::Equal => panic!(),
71                                Ordering::Greater => self.numerator -= self.denominator,
72                            }
73                        } else {
74                            self.set_zero();
75                        }
76                    }
77                }
78            }
79        }
80
81        impl Sub<One> for $name {
82            type Output = Self;
83
84            #[inline]
85            fn sub(mut self, _: One) -> Self::Output {
86                SubAssign::sub_assign(&mut self, One);
87                self
88            }
89        }
90
91        impl Sub<&One> for $name {
92            type Output = Self;
93
94            #[inline]
95            fn sub(mut self, _: &One) -> Self::Output {
96                SubAssign::sub_assign(&mut self, One);
97                self
98            }
99        }
100
101        impl SubAssign<One> for $name {
102            #[inline]
103            fn sub_assign(&mut self, _: One) {
104                SubAssign::sub_assign(self, &One);
105            }
106        }
107
108        impl SubAssign<&One> for $name {
109            #[inline]
110            fn sub_assign(&mut self, _: &One) {
111                match self.sign {
112                    Sign::Positive => {
113                        if self.numerator != 1 || self.denominator != 1 {
114                            match self.numerator.cmp(&self.denominator) {
115                                Ordering::Less => {
116                                    self.numerator = self.denominator - self.numerator;
117                                    self.sign = Sign::Negative;
118                                }
119                                Ordering::Equal => panic!(),
120                                Ordering::Greater => self.numerator -= self.denominator,
121                            }
122                        } else {
123                            self.set_zero();
124                        }
125                    }
126                    Sign::Zero => {
127                        self.sign = Sign::Negative;
128                        debug_assert_eq!(self.numerator, 0);
129                        self.numerator = 1;
130                        debug_assert_eq!(self.denominator, 1);
131                    }
132                    Sign::Negative => self.numerator += self.denominator,
133                }
134            }
135        }
136
137        impl Mul<One> for $name {
138            type Output = Self;
139
140            #[inline]
141            fn mul(self, _: One) -> Self::Output {
142                self
143            }
144        }
145
146        impl Mul<&One> for $name {
147            type Output = Self;
148
149            #[inline]
150            fn mul(self, _: &One) -> Self::Output {
151                self
152            }
153        }
154
155        impl Mul<&One> for &$name {
156            type Output = $name;
157
158            #[inline]
159            fn mul(self, _: &One) -> Self::Output {
160                self.clone()
161            }
162        }
163
164        impl Mul<One> for &$name {
165            type Output = $name;
166
167            #[inline]
168            fn mul(self, _: One) -> Self::Output {
169                self.clone()
170            }
171        }
172
173        impl MulAssign<One> for $name {
174            #[inline]
175            fn mul_assign(&mut self, _: One) {
176                MulAssign::mul_assign(self, &One);
177            }
178        }
179
180        impl MulAssign<&One> for $name {
181            #[inline]
182            fn mul_assign(&mut self, _: &One) {
183            }
184        }
185
186        impl Div<One> for $name {
187            type Output = Self;
188
189            #[inline]
190            fn div(self, _: One) -> Self::Output {
191                self
192            }
193        }
194
195        impl Div<&One> for $name {
196            type Output = Self;
197
198            #[inline]
199            fn div(self, _: &One) -> Self::Output {
200                self
201            }
202        }
203
204        impl Div<&One> for &$name {
205            type Output = $name;
206
207            #[inline]
208            fn div(self, _: &One) -> Self::Output {
209                self.clone()
210            }
211        }
212
213        impl Div<One> for &$name {
214            type Output = $name;
215
216            #[inline]
217            fn div(self, _: One) -> Self::Output {
218                self.clone()
219            }
220        }
221
222        impl DivAssign<One> for $name {
223            #[inline]
224            fn div_assign(&mut self, _: One) {
225                DivAssign::div_assign(self, &One);
226            }
227        }
228
229        impl DivAssign<&One> for $name {
230            #[inline]
231            fn div_assign(&mut self, _: &One) {
232            }
233        }
234    }
235}
236
237impls!(Rational8);
238impls!(Rational16);
239impls!(Rational32);
240impls!(Rational64);
241impls!(Rational128);
242
243#[cfg(test)]
244mod test {
245    use crate::{R8};
246    use crate::fixed::One;
247
248    #[test]
249    fn test_add_sub() {
250        assert_eq!(R8!(1) + One, R8!(2));
251        assert_eq!(R8!(0) + One, R8!(1));
252        assert_eq!(R8!(0) - One, R8!(-1));
253        assert_eq!(R8!(1) - One, R8!(0));
254        assert_eq!(R8!(1, 2) - One, R8!(-1, 2));
255        assert_eq!(R8!(-1, 2) + One, R8!(1, 2));
256        assert_eq!(R8!(-1, 2) - One, R8!(-3, 2));
257
258        assert_eq!(R8!(1) * &One, R8!(1));
259        assert_eq!(R8!(1) / &One, R8!(1));
260    }
261}