1use crate::cbig::CBig;
8use crate::repr::Context;
9use core::cmp::Ordering;
10use dashu_base::AbsOrd;
11use dashu_float::round::Round;
12use dashu_float::Repr;
13use dashu_int::Word;
14
15pub(crate) fn lex_cmp<const B: Word>(
18 re1: &Repr<B>,
19 im1: &Repr<B>,
20 re2: &Repr<B>,
21 im2: &Repr<B>,
22) -> Ordering {
23 match re1.cmp(re2) {
24 Ordering::Equal => im1.cmp(im2),
25 ord => ord,
26 }
27}
28
29impl<R1: Round, R2: Round, const B: Word> PartialEq<CBig<R2, B>> for CBig<R1, B> {
30 #[inline]
33 fn eq(&self, other: &CBig<R2, B>) -> bool {
34 self.re == other.re && self.im == other.im
35 }
36}
37impl<R: Round, const B: Word> Eq for CBig<R, B> {}
38
39impl<R1: Round, R2: Round, const B: Word> PartialOrd<CBig<R2, B>> for CBig<R1, B> {
40 #[inline]
41 fn partial_cmp(&self, other: &CBig<R2, B>) -> Option<Ordering> {
42 Some(lex_cmp(&self.re, &self.im, &other.re, &other.im))
43 }
44}
45
46impl<R: Round, const B: Word> Ord for CBig<R, B> {
47 #[inline]
50 fn cmp(&self, other: &Self) -> Ordering {
51 lex_cmp(&self.re, &self.im, &other.re, &other.im)
52 }
53}
54
55impl<R: Round, const B: Word> AbsOrd for CBig<R, B> {
56 #[inline]
59 fn abs_cmp(&self, other: &Self) -> Ordering {
60 let unlim = Context::<R>::new(0);
62 let f = unlim.float();
63 let n1 = f.unwrap_fp(unlim.norm(self));
64 let n2 = f.unwrap_fp(unlim.norm(other));
65 n1.cmp(&n2)
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use super::*;
72 use dashu_float::round::mode;
73
74 type C = CBig<mode::HalfAway, 10>;
75
76 #[test]
77 fn eq_componentwise() {
78 let a = C::from_parts(3.into(), 4.into());
79 let b = C::from_parts(3.into(), 4.into());
80 assert!(a == b);
81 let c = C::from_parts(3.into(), 5.into());
82 assert!(a != c);
83 }
84
85 #[test]
86 fn signed_zero_eq() {
87 let p = C::from_parts(3.into(), 0.into());
88 let n = C::new(Repr::new(3.into(), 0), Repr::neg_zero(), Context::new(0));
89 assert!(p == n);
91 }
92
93 #[test]
94 fn ord_lexicographic() {
95 let a = C::from_parts(1.into(), 9.into());
96 let b = C::from_parts(2.into(), 0.into());
97 assert!(a < b); let c = C::from_parts(1.into(), 10.into());
99 assert!(a < c); }
101
102 #[test]
103 fn absord_by_magnitude() {
104 let a = C::from_parts(3.into(), 4.into()); let b = C::from_parts(5.into(), 0.into()); assert!(a.abs_cmp(&b).is_eq());
107 let c = C::from_parts(1.into(), 1.into()); assert!(c.abs_cmp(&a).is_lt());
109 }
110}