1#![allow(deprecated)]
17
18use crate::float_helper;
19use crate::int_helper;
20use crate::int_helper::IntFixed;
21use crate::types::extra::Unsigned;
22use crate::{
23 F128, F128Bits, FixedI8, FixedI16, FixedI32, FixedI64, FixedI128, FixedU8, FixedU16, FixedU32,
24 FixedU64, FixedU128,
25};
26use core::cmp::Ordering;
27use core::ops::{Shl, Shr};
28use half::{bf16 as half_bf16, f16 as half_f16};
29
30macro_rules! fixed_cmp_int {
31 ($Fixed:ident, $Int:ident) => {
32 impl<Frac: Unsigned> PartialEq<$Int> for $Fixed<Frac> {
33 #[inline]
34 fn eq(&self, rhs: &$Int) -> bool {
35 let fixed_rhs = IntFixed(*rhs).fixed();
36 PartialEq::eq(self, &fixed_rhs)
37 }
38 }
39
40 impl<Frac: Unsigned> PartialEq<$Fixed<Frac>> for $Int {
41 #[inline]
42 fn eq(&self, rhs: &$Fixed<Frac>) -> bool {
43 let fixed_lhs = IntFixed(*self).fixed();
44 PartialEq::eq(&fixed_lhs, rhs)
45 }
46 }
47
48 impl<Frac: Unsigned> PartialOrd<$Int> for $Fixed<Frac> {
49 #[inline]
50 fn partial_cmp(&self, rhs: &$Int) -> Option<Ordering> {
51 let fixed_rhs = IntFixed(*rhs).fixed();
52 PartialOrd::partial_cmp(self, &fixed_rhs)
53 }
54
55 #[inline]
56 fn lt(&self, rhs: &$Int) -> bool {
57 let fixed_rhs = IntFixed(*rhs).fixed();
58 PartialOrd::lt(self, &fixed_rhs)
59 }
60
61 #[inline]
62 fn le(&self, rhs: &$Int) -> bool {
63 let fixed_rhs = IntFixed(*rhs).fixed();
64 PartialOrd::le(self, &fixed_rhs)
65 }
66
67 #[inline]
68 fn gt(&self, rhs: &$Int) -> bool {
69 let fixed_rhs = IntFixed(*rhs).fixed();
70 PartialOrd::gt(self, &fixed_rhs)
71 }
72
73 #[inline]
74 fn ge(&self, rhs: &$Int) -> bool {
75 let fixed_rhs = IntFixed(*rhs).fixed();
76 PartialOrd::ge(self, &fixed_rhs)
77 }
78 }
79
80 impl<Frac: Unsigned> PartialOrd<$Fixed<Frac>> for $Int {
81 #[inline]
82 fn partial_cmp(&self, rhs: &$Fixed<Frac>) -> Option<Ordering> {
83 let fixed_lhs = IntFixed(*self).fixed();
84 PartialOrd::partial_cmp(&fixed_lhs, rhs)
85 }
86
87 #[inline]
88 fn lt(&self, rhs: &$Fixed<Frac>) -> bool {
89 let fixed_lhs = IntFixed(*self).fixed();
90 PartialOrd::lt(&fixed_lhs, rhs)
91 }
92
93 #[inline]
94 fn le(&self, rhs: &$Fixed<Frac>) -> bool {
95 let fixed_lhs = IntFixed(*self).fixed();
96 PartialOrd::le(&fixed_lhs, rhs)
97 }
98
99 #[inline]
100 fn gt(&self, rhs: &$Fixed<Frac>) -> bool {
101 let fixed_lhs = IntFixed(*self).fixed();
102 PartialOrd::gt(&fixed_lhs, rhs)
103 }
104
105 #[inline]
106 fn ge(&self, rhs: &$Fixed<Frac>) -> bool {
107 let fixed_lhs = IntFixed(*self).fixed();
108 PartialOrd::ge(&fixed_lhs, rhs)
109 }
110 }
111 };
112}
113
114struct Value<U> {
116 neg: bool,
117 abs: U,
118 bits: u32,
119 frac_bits: i32,
120}
121
122#[inline]
123fn float_rhs_shl<U>(rhs_abs: U, bits: u32, lhs_frac: i32, rhs_frac: i32) -> Option<U>
125where
126 U: Copy + Eq + TryFrom<u32> + Shl<u32, Output = U> + Shr<u32, Output = U>,
127{
128 debug_assert!(lhs_frac >= rhs_frac);
129 let rhs_shl = lhs_frac.wrapping_sub(rhs_frac) as u32;
130 let Ok(rhs_zero) = U::try_from(0u32) else {
131 unreachable!();
132 };
133 if rhs_abs == rhs_zero {
134 Some(rhs_zero)
135 } else if rhs_shl >= bits {
136 None
137 } else {
138 let shifted = rhs_abs << rhs_shl;
139 if (shifted >> rhs_shl) == rhs_abs {
140 Some(shifted)
141 } else {
142 None
143 }
144 }
145}
146
147#[inline]
148fn float_eq_even<U>(lhs: Value<U>, rhs: Value<U>) -> bool
149where
150 U: Copy + Eq + TryFrom<u32> + Shl<u32, Output = U> + Shr<u32, Output = U>,
151{
152 if lhs.frac_bits < rhs.frac_bits {
153 return float_eq_even(rhs, lhs);
154 }
155
156 if lhs.neg != rhs.neg {
157 return false;
158 }
159
160 match float_rhs_shl(rhs.abs, rhs.bits, lhs.frac_bits, rhs.frac_bits) {
162 None => false,
163 Some(shifted_rhs_abs) => lhs.abs == shifted_rhs_abs,
164 }
165}
166
167#[inline]
168fn float_eq<Lhs, Rhs>(lhs: Value<Lhs>, rhs: Value<Rhs>) -> bool
169where
170 Lhs: Copy + Eq + TryFrom<u32> + TryFrom<Rhs> + Shl<u32, Output = Lhs> + Shr<u32, Output = Lhs>,
171 Rhs: Copy + Eq + TryFrom<u32> + TryFrom<Lhs> + Shl<u32, Output = Rhs> + Shr<u32, Output = Rhs>,
172{
173 if lhs.bits >= rhs.bits {
174 let Ok(rhs_abs) = Lhs::try_from(rhs.abs) else {
175 unreachable!();
176 };
177 let rhs = Value {
178 neg: rhs.neg,
179 abs: rhs_abs,
180 bits: lhs.bits,
181 frac_bits: rhs.frac_bits,
182 };
183 float_eq_even(lhs, rhs)
184 } else {
185 let Ok(lhs_abs) = Rhs::try_from(lhs.abs) else {
186 unreachable!();
187 };
188 let lhs = Value {
189 neg: lhs.neg,
190 abs: lhs_abs,
191 bits: rhs.bits,
192 frac_bits: lhs.frac_bits,
193 };
194 float_eq_even(lhs, rhs)
195 }
196}
197
198#[inline]
199fn float_cmp_even<U>(lhs: Value<U>, rhs: Value<U>) -> Ordering
200where
201 U: Copy + Ord + TryFrom<u32> + Shl<u32, Output = U> + Shr<u32, Output = U>,
202{
203 if lhs.frac_bits < rhs.frac_bits {
204 return float_cmp_even(rhs, lhs).reverse();
205 }
206
207 if !lhs.neg && rhs.neg {
208 return Ordering::Greater;
209 }
210 if lhs.neg && !rhs.neg {
211 return Ordering::Less;
212 }
213
214 match float_rhs_shl(rhs.abs, rhs.bits, lhs.frac_bits, rhs.frac_bits) {
215 None => {
216 if lhs.neg {
218 Ordering::Greater
220 } else {
221 Ordering::Less
222 }
223 }
224 Some(shifted_rhs_abs) => {
225 if lhs.neg {
226 shifted_rhs_abs.cmp(&lhs.abs)
228 } else {
229 lhs.abs.cmp(&shifted_rhs_abs)
230 }
231 }
232 }
233}
234
235#[inline]
236fn float_cmp<Lhs, Rhs>(lhs: Value<Lhs>, rhs: Value<Rhs>) -> Ordering
237where
238 Lhs: Copy + Ord + TryFrom<u32> + TryFrom<Rhs> + Shl<u32, Output = Lhs> + Shr<u32, Output = Lhs>,
239 Rhs: Copy + Ord + TryFrom<u32> + TryFrom<Lhs> + Shl<u32, Output = Rhs> + Shr<u32, Output = Rhs>,
240{
241 if lhs.bits >= rhs.bits {
242 let Ok(rhs_abs) = Lhs::try_from(rhs.abs) else {
243 unreachable!();
244 };
245 let rhs = Value {
246 neg: rhs.neg,
247 abs: rhs_abs,
248 bits: lhs.bits,
249 frac_bits: rhs.frac_bits,
250 };
251 float_cmp_even(lhs, rhs)
252 } else {
253 let Ok(lhs_abs) = Rhs::try_from(lhs.abs) else {
254 unreachable!();
255 };
256 let lhs = Value {
257 neg: lhs.neg,
258 abs: lhs_abs,
259 bits: rhs.bits,
260 frac_bits: lhs.frac_bits,
261 };
262 float_cmp_even(lhs, rhs)
263 }
264}
265
266macro_rules! fixed_cmp_float {
267 ($Fix:ident($Inner:ident), $Float:ident, $FloatBits:ident) => {
268 impl<Frac: Unsigned> PartialEq<$Float> for $Fix<Frac> {
269 #[inline]
270 fn eq(&self, rhs: &$Float) -> bool {
271 use float_helper::$Float::Kind;
272 let (lhs_neg, lhs_abs) = int_helper::$Inner::neg_abs(self.to_bits());
273 let lhs = Value {
274 neg: lhs_neg,
275 abs: lhs_abs,
276 bits: $Inner::BITS,
277 frac_bits: Frac::to_i32(),
278 };
279 let Kind::Finite {
280 neg: rhs_neg,
281 abs: rhs_abs,
282 frac_bits: rhs_frac,
283 } = float_helper::$Float::kind(*rhs)
284 else {
285 return false;
286 };
287 let rhs = Value {
288 neg: rhs_neg,
289 abs: rhs_abs,
290 bits: $FloatBits::BITS,
291 frac_bits: rhs_frac,
292 };
293
294 float_eq(lhs, rhs)
295 }
296 }
297
298 impl<Frac: Unsigned> PartialEq<$Fix<Frac>> for $Float {
299 #[inline]
300 fn eq(&self, rhs: &$Fix<Frac>) -> bool {
301 rhs.eq(self)
302 }
303 }
304
305 impl<Frac: Unsigned> PartialOrd<$Float> for $Fix<Frac> {
306 #[inline]
307 fn partial_cmp(&self, rhs: &$Float) -> Option<Ordering> {
308 use float_helper::$Float::Kind;
309 let (lhs_neg, lhs_abs) = int_helper::$Inner::neg_abs(self.to_bits());
310 let lhs = Value {
311 neg: lhs_neg,
312 abs: lhs_abs,
313 bits: $Inner::BITS,
314 frac_bits: Frac::to_i32(),
315 };
316 let (rhs_neg, rhs_abs, rhs_frac) = match float_helper::$Float::kind(*rhs) {
317 Kind::Finite {
318 neg,
319 abs,
320 frac_bits,
321 } => (neg, abs, frac_bits),
322 Kind::Infinite { neg } => {
323 return if neg {
324 Some(Ordering::Greater)
325 } else {
326 Some(Ordering::Less)
327 };
328 }
329 Kind::NaN => return None,
330 };
331 let rhs = Value {
332 neg: rhs_neg,
333 abs: rhs_abs,
334 bits: $FloatBits::BITS,
335 frac_bits: rhs_frac,
336 };
337
338 Some(float_cmp(lhs, rhs))
339 }
340 }
341
342 impl<Frac: Unsigned> PartialOrd<$Fix<Frac>> for $Float {
343 #[inline]
344 fn partial_cmp(&self, rhs: &$Fix<Frac>) -> Option<Ordering> {
345 rhs.partial_cmp(self).map(Ordering::reverse)
346 }
347 }
348 };
349}
350
351macro_rules! fixed_cmp_all {
352 ($Fix:ident($LeEqU:ident, $Inner:ident)) => {
353 fixed_cmp_int! { $Fix, i8 }
354 fixed_cmp_int! { $Fix, i16 }
355 fixed_cmp_int! { $Fix, i32 }
356 fixed_cmp_int! { $Fix, i64 }
357 fixed_cmp_int! { $Fix, i128 }
358 fixed_cmp_int! { $Fix, isize }
359 fixed_cmp_int! { $Fix, u8 }
360 fixed_cmp_int! { $Fix, u16 }
361 fixed_cmp_int! { $Fix, u32 }
362 fixed_cmp_int! { $Fix, u64 }
363 fixed_cmp_int! { $Fix, u128 }
364 fixed_cmp_int! { $Fix, usize }
365 #[cfg(feature = "nightly-float")]
366 fixed_cmp_float! { $Fix($Inner), f16, u16 }
367 fixed_cmp_float! { $Fix($Inner), half_f16, u16 }
368 fixed_cmp_float! { $Fix($Inner), half_bf16, u16 }
369 fixed_cmp_float! { $Fix($Inner), f32, u32 }
370 fixed_cmp_float! { $Fix($Inner), f64, u64 }
371 #[cfg(feature = "nightly-float")]
372 fixed_cmp_float! { $Fix($Inner), f128, u128 }
373 fixed_cmp_float! { $Fix($Inner), F128, u128 }
374 fixed_cmp_float! { $Fix($Inner), F128Bits, u128 }
375 };
376}
377
378fixed_cmp_all! { FixedI8(LeEqU8, i8) }
379fixed_cmp_all! { FixedI16(LeEqU16, i16) }
380fixed_cmp_all! { FixedI32(LeEqU32, i32) }
381fixed_cmp_all! { FixedI64(LeEqU64, i64) }
382fixed_cmp_all! { FixedI128(LeEqU128, i128) }
383fixed_cmp_all! { FixedU8(LeEqU8, u8) }
384fixed_cmp_all! { FixedU16(LeEqU16, u16) }
385fixed_cmp_all! { FixedU32(LeEqU32, u32) }
386fixed_cmp_all! { FixedU64(LeEqU64, u64) }
387fixed_cmp_all! { FixedU128(LeEqU128, u128) }
388
389#[cfg(test)]
390mod tests {
391 use crate::*;
392 use core::cmp::Ordering;
393
394 #[test]
395 fn cmp_signed() {
396 use core::cmp::Ordering::*;
397 let neg1_16 = FixedI32::<types::extra::U16>::NEG_ONE;
398 let neg1_20 = FixedI32::<types::extra::U20>::NEG_ONE;
399 let mut a = neg1_16;
400 let mut b = neg1_20;
401 assert!(a.eq(&b) && b.eq(&a));
403 assert_eq!(a.partial_cmp(&b), Some(Equal));
404 assert_eq!(b.partial_cmp(&a), Some(Equal));
405 assert_eq!(a, -1i8);
406 assert_eq!(b, -1i128);
407 a >>= 16;
408 b >>= 16;
409 assert!(a.eq(&b) && b.eq(&a));
411 assert_eq!(a.partial_cmp(&b), Some(Equal));
412 assert_eq!(b.partial_cmp(&a), Some(Equal));
413 assert!(a < 0.0);
414 assert_eq!(a.partial_cmp(&f32::INFINITY), Some(Less));
415 assert!(a < f32::INFINITY);
416 assert!(a != f32::INFINITY);
417 assert_eq!(a.partial_cmp(&f32::NEG_INFINITY), Some(Greater));
418 assert!(a > f32::NEG_INFINITY);
419 assert_eq!(a, -(-16f32).exp2());
420 assert!(a <= -(-16f32).exp2());
421 assert!(a >= -(-16f32).exp2());
422 assert!(a < (-16f32).exp2());
423 assert_ne!(a, -0.75 * (-16f32).exp2());
424 assert!(a < -0.75 * (-16f32).exp2());
425 assert!(a <= -0.75 * (-16f32).exp2());
426 assert!(a > -1.25 * (-16f32).exp2());
427 assert!(a >= -1.25 * (-16f32).exp2());
428 a >>= 1;
429 b >>= 1;
430 assert!(a.ne(&b) && b.ne(&a));
432 assert_eq!(a.partial_cmp(&b), Some(Less));
433 assert_eq!(b.partial_cmp(&a), Some(Greater));
434 a = neg1_16 << 11;
435 b = neg1_20 << 11;
436 assert!(a.eq(&b) && b.eq(&a));
438 assert_eq!(a.partial_cmp(&b), Some(Equal));
439 assert_eq!(b.partial_cmp(&a), Some(Equal));
440 assert_eq!(a, -1i16 << 11);
441 assert_eq!(b, -1i64 << 11);
442 a <<= 1;
443 b <<= 1;
444 assert!(a.ne(&b) && b.ne(&a));
446 assert_eq!(a.partial_cmp(&b), Some(Less));
447 assert_eq!(b.partial_cmp(&a), Some(Greater));
448 assert!(a < 1u8);
449 assert_eq!(b, 0);
450 }
451
452 #[test]
453 fn cmp_unsigned() {
454 use core::cmp::Ordering::*;
455 let one_16 = FixedU32::<types::extra::U16>::ONE;
456 let one_20 = FixedU32::<types::extra::U20>::ONE;
457 let mut a = one_16;
458 let mut b = one_20;
459 assert!(a.eq(&b) && b.eq(&a));
461 assert_eq!(a.partial_cmp(&b), Some(Equal));
462 assert_eq!(b.partial_cmp(&a), Some(Equal));
463 assert_eq!(a, 1u8);
464 assert_eq!(b, 1i128);
465 a >>= 16;
466 b >>= 16;
467 assert!(a.eq(&b) && b.eq(&a));
469 assert_eq!(a.partial_cmp(&b), Some(Equal));
470 assert_eq!(b.partial_cmp(&a), Some(Equal));
471 assert!(a > 0.0);
472 assert_eq!(a.partial_cmp(&f32::INFINITY), Some(Less));
473 assert!(a < f32::INFINITY);
474 assert!(a != f32::INFINITY);
475 assert_eq!(a.partial_cmp(&f32::NEG_INFINITY), Some(Greater));
476 assert!(a > f32::NEG_INFINITY);
477 assert_eq!(a, (-16f64).exp2());
478 assert!(a <= (-16f64).exp2());
479 assert!(a >= (-16f64).exp2());
480 assert!(a > -(-16f64).exp2());
481 assert_ne!(a, 0.75 * (-16f64).exp2());
482 assert!(a > 0.75 * (-16f64).exp2());
483 assert!(a >= 0.75 * (-16f64).exp2());
484 assert!(a < 1.25 * (-16f64).exp2());
485 assert!(a <= 1.25 * (-16f64).exp2());
486 a >>= 1;
487 b >>= 1;
488 assert!(a.ne(&b) && b.ne(&a));
490 assert_eq!(a.partial_cmp(&b), Some(Less));
491 assert_eq!(b.partial_cmp(&a), Some(Greater));
492 a = one_16 << 11;
493 b = one_20 << 11;
494 assert!(a.eq(&b) && b.eq(&a));
496 assert_eq!(a.partial_cmp(&b), Some(Equal));
497 assert_eq!(b.partial_cmp(&a), Some(Equal));
498 assert_eq!(a, 1i16 << 11);
499 assert_eq!(b, 1u64 << 11);
500 a <<= 1;
501 b <<= 1;
502 assert!(a.ne(&b) && b.ne(&a));
504 assert_eq!(a.partial_cmp(&b), Some(Greater));
505 assert_eq!(b.partial_cmp(&a), Some(Less));
506 assert!(a > -1i8);
507 assert_eq!(a, 1i32 << 12);
508 assert_eq!(b, 0);
509 }
510
511 #[test]
512 fn cmp_i0() {
513 use crate::types::*;
514 assert_eq!(I0F32::checked_from_num(0.5), None);
515 for &float in &[
516 -0.5,
517 -0.5 + f32::EPSILON,
518 -0.25,
519 -f32::EPSILON,
520 0.0,
521 f32::EPSILON,
522 0.25,
523 0.5 - f32::EPSILON,
524 ] {
525 let fixed = I0F32::from_num(float);
526 let half = U0F32::from_num(0.5);
527 assert_eq!(fixed < half, float < 0.5, "{fixed} < {half}");
528 assert_eq!(fixed <= half, float <= 0.5, "{fixed} <= {half}");
529 assert_eq!(fixed == half, float == 0.5, "{fixed} == {half}");
530 assert_eq!(fixed >= half, float >= 0.5, "{fixed} >= {half}");
531 assert_eq!(fixed > half, float > 0.5, "{fixed} > {half}");
532 assert_eq!(
533 fixed.partial_cmp(&half),
534 float.partial_cmp(&0.5),
535 "{fixed}.partial_cmp(&{half})"
536 );
537 assert_eq!(half < fixed, fixed > half);
538 assert_eq!(half <= fixed, fixed >= half);
539 assert_eq!(half == fixed, fixed == half);
540 assert_eq!(half >= fixed, fixed <= half);
541 assert_eq!(half > fixed, fixed < half);
542 assert_eq!(
543 half.partial_cmp(&fixed),
544 fixed.partial_cmp(&half).map(Ordering::reverse)
545 );
546
547 let half = I1F31::from_num(0.5);
548 assert_eq!(fixed < half, float < 0.5, "{fixed} < {half}");
549 assert_eq!(fixed <= half, float <= 0.5, "{fixed} <= {half}");
550 assert_eq!(fixed == half, float == 0.5, "{fixed} == {half}");
551 assert_eq!(fixed >= half, float >= 0.5, "{fixed} >= {half}");
552 assert_eq!(fixed > half, float > 0.5, "{fixed} > {half}");
553 assert_eq!(
554 fixed.partial_cmp(&half),
555 float.partial_cmp(&0.5),
556 "{fixed}.partial_cmp(&{half})"
557 );
558 assert_eq!(half < fixed, fixed > half);
559 assert_eq!(half <= fixed, fixed >= half);
560 assert_eq!(half == fixed, fixed == half);
561 assert_eq!(half >= fixed, fixed <= half);
562 assert_eq!(half > fixed, fixed < half);
563 assert_eq!(
564 half.partial_cmp(&fixed),
565 fixed.partial_cmp(&half).map(Ordering::reverse)
566 );
567
568 let half = 0.5f32;
569 assert_eq!(fixed < half, float < 0.5, "{fixed} < {half}");
570 assert_eq!(fixed <= half, float <= 0.5, "{fixed} <= {half}");
571 assert_eq!(fixed == half, float == 0.5, "{fixed} == {half}");
572 assert_eq!(fixed >= half, float >= 0.5, "{fixed} >= {half}");
573 assert_eq!(fixed > half, float > 0.5, "{fixed} > {half}");
574 assert_eq!(
575 fixed.partial_cmp(&half),
576 float.partial_cmp(&0.5),
577 "{fixed}.partial_cmp(&{half})"
578 );
579 assert_eq!(half < fixed, fixed > half);
580 assert_eq!(half <= fixed, fixed >= half);
581 assert_eq!(half == fixed, fixed == half);
582 assert_eq!(half >= fixed, fixed <= half);
583 assert_eq!(half > fixed, fixed < half);
584 assert_eq!(
585 half.partial_cmp(&fixed),
586 fixed.partial_cmp(&half).map(Ordering::reverse)
587 );
588
589 let m1 = I32F0::from_num(-1.0);
590 assert_eq!(fixed < m1, float < -1.0, "{fixed} < {m1}");
591 assert_eq!(fixed <= m1, float <= -1.0, "{fixed} <= {m1}");
592 assert_eq!(fixed == m1, float == -1.0, "{fixed} == {m1}");
593 assert_eq!(fixed >= m1, float >= -1.0, "{fixed} >= {m1}");
594 assert_eq!(fixed > m1, float > -1.0, "{fixed} > {m1}");
595 assert_eq!(
596 fixed.partial_cmp(&m1),
597 float.partial_cmp(&-1.0),
598 "{fixed}.partial_cmp(&{m1})"
599 );
600 assert_eq!(m1 < fixed, fixed > m1);
601 assert_eq!(m1 <= fixed, fixed >= m1);
602 assert_eq!(m1 == fixed, fixed == m1);
603 assert_eq!(m1 >= fixed, fixed <= m1);
604 assert_eq!(m1 > fixed, fixed < m1);
605 assert_eq!(
606 m1.partial_cmp(&fixed),
607 fixed.partial_cmp(&m1).map(Ordering::reverse)
608 );
609
610 let m1 = I1F31::from_num(-1.0);
611 assert_eq!(fixed < m1, float < -1.0, "{fixed} < {m1}");
612 assert_eq!(fixed <= m1, float <= -1.0, "{fixed} <= {m1}");
613 assert_eq!(fixed == m1, float == -1.0, "{fixed} == {m1}");
614 assert_eq!(fixed >= m1, float >= -1.0, "{fixed} >= {m1}");
615 assert_eq!(fixed > m1, float > -1.0, "{fixed} > {m1}");
616 assert_eq!(
617 fixed.partial_cmp(&m1),
618 float.partial_cmp(&-1.0),
619 "{fixed}.partial_cmp(&{m1})"
620 );
621 assert_eq!(m1 < fixed, fixed > m1);
622 assert_eq!(m1 <= fixed, fixed >= m1);
623 assert_eq!(m1 == fixed, fixed == m1);
624 assert_eq!(m1 >= fixed, fixed <= m1);
625 assert_eq!(m1 > fixed, fixed < m1);
626 assert_eq!(
627 m1.partial_cmp(&fixed),
628 fixed.partial_cmp(&m1).map(Ordering::reverse)
629 );
630
631 let m1 = -1.0f32;
632 assert_eq!(fixed < m1, float < -1.0, "{fixed} < {m1}");
633 assert_eq!(fixed <= m1, float <= -1.0, "{fixed} <= {m1}");
634 assert_eq!(fixed == m1, float == -1.0, "{fixed} == {m1}");
635 assert_eq!(fixed >= m1, float >= -1.0, "{fixed} >= {m1}");
636 assert_eq!(fixed > m1, float > -1.0, "{fixed} > {m1}");
637 assert_eq!(
638 fixed.partial_cmp(&m1),
639 float.partial_cmp(&-1.0),
640 "{fixed}.partial_cmp(&{m1})"
641 );
642 assert_eq!(m1 < fixed, fixed > m1);
643 assert_eq!(m1 <= fixed, fixed >= m1);
644 assert_eq!(m1 == fixed, fixed == m1);
645 assert_eq!(m1 >= fixed, fixed <= m1);
646 assert_eq!(m1 > fixed, fixed < m1);
647 assert_eq!(
648 m1.partial_cmp(&fixed),
649 fixed.partial_cmp(&m1).map(Ordering::reverse)
650 );
651
652 let mhalf = I1F31::from_num(-0.5);
653 assert_eq!(fixed < mhalf, float < -0.5, "{fixed} < {mhalf}");
654 assert_eq!(fixed <= mhalf, float <= -0.5, "{fixed} <= {mhalf}");
655 assert_eq!(fixed == mhalf, float == -0.5, "{fixed} == {mhalf}");
656 assert_eq!(fixed >= mhalf, float >= -0.5, "{fixed} >= {mhalf}");
657 assert_eq!(fixed > mhalf, float > -0.5, "{fixed} > {mhalf}");
658 assert_eq!(
659 fixed.partial_cmp(&mhalf),
660 float.partial_cmp(&-0.5),
661 "{fixed}.partial_cmp(&{mhalf})"
662 );
663 assert_eq!(mhalf < fixed, fixed > mhalf);
664 assert_eq!(mhalf <= fixed, fixed >= mhalf);
665 assert_eq!(mhalf == fixed, fixed == mhalf);
666 assert_eq!(mhalf >= fixed, fixed <= mhalf);
667 assert_eq!(mhalf > fixed, fixed < mhalf);
668 assert_eq!(
669 mhalf.partial_cmp(&fixed),
670 fixed.partial_cmp(&mhalf).map(Ordering::reverse)
671 );
672
673 let mhalf = -0.5f32;
674 assert_eq!(fixed < mhalf, float < -0.5, "{fixed} < {mhalf}");
675 assert_eq!(fixed <= mhalf, float <= -0.5, "{fixed} <= {mhalf}");
676 assert_eq!(fixed == mhalf, float == -0.5, "{fixed} == {mhalf}");
677 assert_eq!(fixed >= mhalf, float >= -0.5, "{fixed} >= {mhalf}");
678 assert_eq!(fixed > mhalf, float > -0.5, "{fixed} > {mhalf}");
679 assert_eq!(
680 fixed.partial_cmp(&mhalf),
681 float.partial_cmp(&-0.5),
682 "{fixed}.partial_cmp(&{mhalf})"
683 );
684 assert_eq!(mhalf < fixed, fixed > mhalf);
685 assert_eq!(mhalf <= fixed, fixed >= mhalf);
686 assert_eq!(mhalf == fixed, fixed == mhalf);
687 assert_eq!(mhalf >= fixed, fixed <= mhalf);
688 assert_eq!(mhalf > fixed, fixed < mhalf);
689 assert_eq!(
690 mhalf.partial_cmp(&fixed),
691 fixed.partial_cmp(&mhalf).map(Ordering::reverse)
692 );
693 }
694 }
695}