nanvm_lib/vm/bigint/
cmp.rs1use crate::vm::{IVm, bigint::BigInt};
2use std::cmp::Ordering;
3
4impl<A: IVm> PartialOrd for BigInt<A> {
5 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
6 Some(self.cmp(other))
7 }
8}
9
10impl<A: IVm> Ord for BigInt<A> {
19 fn cmp(&self, rhs: &Self) -> Ordering {
20 use crate::sign::Sign;
21
22 let sign = self.sign();
23 sign.cmp(&rhs.sign()).then_with(|| match sign {
24 Sign::Positive => self.clone().abs_cmp_vec(rhs.clone()),
25 Sign::Negative => rhs.clone().abs_cmp_vec(self.clone()),
26 })
27 }
28}
29
30#[cfg(test)]
31mod tests {
32 use crate::vm::bigint::test_util::{T, int, neg, pos};
33 use std::cmp::Ordering;
34
35 #[test]
36 fn cmp_positive_vs_negative() {
37 let lhs: T = 1u64.into();
38 let rhs: T = (-1i64).into();
39 assert_eq!(lhs.cmp(&rhs), Ordering::Greater);
40 assert_eq!(rhs.cmp(&lhs), Ordering::Less);
41 }
42
43 #[test]
44 fn cmp_positive_by_absolute_value() {
45 let lhs: T = 5u64.into();
46 let rhs: T = 6u64.into();
47 assert_eq!(lhs.cmp(&rhs), Ordering::Less);
48 assert_eq!(rhs.cmp(&lhs), Ordering::Greater);
49 }
50
51 #[test]
52 fn cmp_negative_reverses_absolute_order() {
53 let lhs: T = (-5i64).into();
54 let rhs: T = (-6i64).into();
55 assert_eq!(lhs.cmp(&rhs), Ordering::Greater);
56 assert_eq!(rhs.cmp(&lhs), Ordering::Less);
57 }
58
59 #[test]
60 fn cmp_equal_values() {
61 let lhs: T = 0u64.into();
62 let rhs: T = 0u64.into();
63 assert_eq!(lhs.cmp(&rhs), Ordering::Equal);
64 }
65
66 fn cases() -> [T; 9] {
70 [
71 int(0),
72 int(1),
73 int(-1),
74 int(5),
75 int(-5),
76 pos([0, 1]),
77 neg([0, 1]),
78 pos([7, 1]),
79 neg([7, 1]),
80 ]
81 }
82
83 #[test]
84 fn eq_agrees_with_cmp() {
85 for (i, a) in cases().iter().enumerate() {
86 for (j, b) in cases().iter().enumerate() {
87 assert_eq!(a == b, a.cmp(b) == Ordering::Equal, "{a:?} vs {b:?}");
88 assert_eq!(a == b, i == j, "{a:?} vs {b:?}");
89 assert_eq!(a.partial_cmp(b), Some(a.cmp(b)), "{a:?} vs {b:?}");
90 assert_eq!(a.cmp(b), b.cmp(a).reverse(), "{a:?} vs {b:?}");
91 }
92 }
93 let negated_zero = -int(0);
95 assert_eq!(negated_zero.cmp(&int(0)), Ordering::Equal);
96 assert!(negated_zero == int(0));
97 }
98}