1use crate::Ratio;
2use std::cmp::Ordering;
3
4impl Ratio {
5
6 pub fn lt_rat(&self, other: &Ratio) -> bool {
8 self.sub_rat(other).is_neg()
10 }
11
12 pub fn gt_rat(&self, other: &Ratio) -> bool {
14 other.sub_rat(self).is_neg()
16 }
17
18 pub fn eq_rat(&self, other: &Ratio) -> bool {
20 self == other
21 }
22
23 pub fn neq_rat(&self, other: &Ratio) -> bool {
25 self != other
26 }
27
28 pub fn leq_rat(&self, other: &Ratio) -> bool {
30 !self.gt_rat(other)
31 }
32
33 pub fn geq_rat(&self, other: &Ratio) -> bool {
35 !self.lt_rat(other)
36 }
37
38 pub fn comp_rat(&self, other: &Ratio) -> Ordering {
39 self.numer.mul_bi(&other.denom).comp_bi(&other.numer.mul_bi(&self.denom))
40 }
41
42 pub fn lt_one(&self) -> bool {
44 self.is_neg() || self.numer.lt_bi(&self.denom)
45 }
46
47 pub fn gt_one(&self) -> bool {
49 !self.is_neg() && self.numer.gt_bi(&self.denom)
50 }
51
52 pub fn lt_i32(&self, other: i32) -> bool {
54 self.numer.lt_bi(&self.denom.mul_i32(other))
55 }
56
57 pub fn gt_i32(&self, other: i32) -> bool {
59 self.numer.gt_bi(&self.denom.mul_i32(other))
60 }
61
62 pub fn eq_i32(&self, other: i32) -> bool {
64 self.denom.is_one() && self.numer.eq_i32(other)
65 }
66
67 pub fn neq_i32(&self, other: i32) -> bool {
69 !self.eq_i32(other)
70 }
71
72 pub fn leq_i32(&self, other: i32) -> bool {
74 !self.gt_i32(other)
75 }
76
77 pub fn geq_i32(&self, other: i32) -> bool {
79 !self.lt_i32(other)
80 }
81
82 pub fn comp_i32(&self, other: i32) -> Ordering {
83 self.numer.comp_bi(&self.denom.mul_i32(other))
84 }
85
86}
87
88impl PartialOrd for Ratio {
89
90 fn partial_cmp(&self, other: &Ratio) -> Option<Ordering> {
91 Some(self.comp_rat(other))
92 }
93
94}
95
96impl Ord for Ratio {
97
98 fn cmp(&self, other: &Ratio) -> Ordering {
99 self.comp_rat(other)
100 }
101
102}
103
104#[cfg(test)]
105mod tests {
106 use crate::Ratio;
107 use std::cmp::Ordering;
108
109 #[test]
110 fn rat_comp_test() {
111
112 for d1 in 1..6 {
113
114 for d2 in 1..6 {
115
116 for n1 in -7..7 {
117
118 for n2 in -7..7 {
119 comp_test_worker(d1, d2, n1, n2);
120 }
121
122 }
123
124 }
125
126 }
127
128 }
129
130 fn comp_test_worker(d1: i32, d2: i32, n1: i32, n2: i32) {
131 let a = Ratio::from_denom_and_numer_i32(d1, n1);
132 let b = Ratio::from_denom_and_numer_i32(d2, n2);
133
134 match a.comp_rat(&b) {
135 Ordering::Greater => {
136 assert!(a.gt_rat(&b));
137 assert!(!a.eq_rat(&b));
138 assert!(!a.lt_rat(&b));
139 }
140 Ordering::Equal => {
141 assert!(!a.gt_rat(&b));
142 assert!(a.eq_rat(&b));
143 assert!(!a.lt_rat(&b));
144 }
145 Ordering::Less => {
146 assert!(!a.gt_rat(&b));
147 assert!(!a.eq_rat(&b));
148 assert!(a.lt_rat(&b));
149 }
150 }
151
152 match a.comp_i32(d2 * n2) {
153 Ordering::Greater => {
154 assert!(a.gt_i32(d2 * n2));
155 assert!(!a.eq_i32(d2 * n2));
156 assert!(!a.lt_i32(d2 * n2));
157 }
158 Ordering::Equal => {
159 assert!(!a.gt_i32(d2 * n2));
160 assert!(a.eq_i32(d2 * n2));
161 assert!(!a.lt_i32(d2 * n2));
162 }
163 Ordering::Less => {
164 assert!(!a.gt_i32(d2 * n2));
165 assert!(!a.eq_i32(d2 * n2));
166 assert!(a.lt_i32(d2 * n2));
167 }
168 }
169
170 assert!(a.lt_one() && a.lt_i32(1) || a.gt_one() && a.gt_i32(1) || a.eq_i32(1));
171 }
172
173}