dashu_int/
cmp.rs

1//! Comparisons operators.
2#![allow(deprecated)] // TODO(v0.5): remove after the implementations for AbsEq are removed.
3
4use dashu_base::{AbsEq, AbsOrd};
5
6use crate::{
7    arch::word::Word,
8    ibig::IBig,
9    repr::TypedReprRef::{self, *},
10    ubig::UBig,
11    Sign::*,
12};
13use core::cmp::Ordering;
14
15/// Compare lhs with rhs of the same length as numbers.
16#[inline]
17pub fn cmp_same_len(lhs: &[Word], rhs: &[Word]) -> Ordering {
18    debug_assert!(lhs.len() == rhs.len());
19    lhs.iter().rev().cmp(rhs.iter().rev())
20}
21
22/// Compare lhs with rhs as numbers. The leading zero words of the input must be trimmed.
23///
24/// # Panics
25///
26/// Panic if lhs or rhs has leading zero words (including the case where lhs == 0 or rhs == 0)
27pub fn cmp_in_place(lhs: &[Word], rhs: &[Word]) -> Ordering {
28    debug_assert!(*lhs.last().unwrap() != 0 && *rhs.last().unwrap() != 0);
29    lhs.len()
30        .cmp(&rhs.len())
31        .then_with(|| cmp_same_len(lhs, rhs))
32}
33
34impl<'a> PartialOrd for TypedReprRef<'a> {
35    #[inline]
36    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
37        Some(self.cmp(other))
38    }
39}
40
41impl<'a> Ord for TypedReprRef<'a> {
42    #[inline]
43    fn cmp(&self, other: &Self) -> Ordering {
44        match (*self, *other) {
45            (RefSmall(dword0), RefSmall(dword1)) => dword0.cmp(&dword1),
46            (RefSmall(_), RefLarge(_)) => Ordering::Less,
47            (RefLarge(_), RefSmall(_)) => Ordering::Greater,
48            (RefLarge(words0), RefLarge(words1)) => cmp_in_place(words0, words1),
49        }
50    }
51}
52
53impl Ord for UBig {
54    #[inline]
55    fn cmp(&self, other: &UBig) -> Ordering {
56        self.repr().cmp(&other.repr())
57    }
58}
59
60impl PartialOrd for UBig {
61    #[inline]
62    fn partial_cmp(&self, other: &UBig) -> Option<Ordering> {
63        Some(self.cmp(other))
64    }
65}
66
67impl Ord for IBig {
68    #[inline]
69    fn cmp(&self, other: &IBig) -> Ordering {
70        let (lhs_sign, lhs_mag) = self.as_sign_repr();
71        let (rhs_sign, rhs_mag) = other.as_sign_repr();
72        match (lhs_sign, rhs_sign) {
73            (Positive, Positive) => lhs_mag.cmp(&rhs_mag),
74            (Positive, Negative) => Ordering::Greater,
75            (Negative, Positive) => Ordering::Less,
76            (Negative, Negative) => rhs_mag.cmp(&lhs_mag),
77        }
78    }
79}
80
81impl PartialOrd for IBig {
82    #[inline]
83    fn partial_cmp(&self, other: &IBig) -> Option<Ordering> {
84        Some(self.cmp(other))
85    }
86}
87
88impl AbsEq for UBig {
89    #[inline]
90    fn abs_eq(&self, rhs: &Self) -> bool {
91        self.eq(rhs)
92    }
93}
94impl AbsEq for IBig {
95    #[inline]
96    fn abs_eq(&self, rhs: &Self) -> bool {
97        self.0.as_sign_slice().1.eq(rhs.0.as_sign_slice().1)
98    }
99}
100impl AbsEq<UBig> for IBig {
101    #[inline]
102    fn abs_eq(&self, rhs: &UBig) -> bool {
103        self.0.as_sign_slice().1.eq(rhs.0.as_slice())
104    }
105}
106impl AbsEq<IBig> for UBig {
107    #[inline]
108    fn abs_eq(&self, rhs: &IBig) -> bool {
109        self.0.as_slice().eq(rhs.0.as_sign_slice().1)
110    }
111}
112
113impl AbsOrd for UBig {
114    #[inline]
115    fn abs_cmp(&self, rhs: &Self) -> Ordering {
116        self.0.as_typed().cmp(&rhs.0.as_typed())
117    }
118}
119impl AbsOrd for IBig {
120    #[inline]
121    fn abs_cmp(&self, rhs: &Self) -> Ordering {
122        self.0.as_sign_typed().1.cmp(&rhs.0.as_sign_typed().1)
123    }
124}
125impl AbsOrd<UBig> for IBig {
126    #[inline]
127    fn abs_cmp(&self, rhs: &UBig) -> Ordering {
128        self.0.as_sign_typed().1.cmp(&rhs.0.as_typed())
129    }
130}
131impl AbsOrd<IBig> for UBig {
132    #[inline]
133    fn abs_cmp(&self, rhs: &IBig) -> Ordering {
134        self.0.as_typed().cmp(&rhs.0.as_sign_typed().1)
135    }
136}