relp_num/integer/big/
properties.rs1use std::cmp::Ordering;
2use std::ops::Deref;
3
4use crate::{NonZero, Sign, Ubig};
5use crate::integer::big::NonZeroUbig;
6use crate::integer::big::ops::building_blocks::is_well_formed;
7use crate::Signed;
8
9impl<const S: usize> NonZero for Ubig<S> {
10 #[inline]
11 fn is_not_zero(&self) -> bool {
12 !self.0.is_empty()
13 }
14}
15
16impl<const S: usize> NonZero for NonZeroUbig<S> {
17 #[inline]
18 fn is_not_zero(&self) -> bool {
19 true
20 }
21}
22
23impl<const S: usize> Deref for Ubig<S> {
24 type Target = [usize];
25
26 fn deref(&self) -> &Self::Target {
27 &self.0
28 }
29}
30
31impl<const S: usize> Deref for NonZeroUbig<S> {
32 type Target = [usize];
33
34 fn deref(&self) -> &Self::Target {
35 &self.0
36 }
37}
38
39impl<const S: usize> Signed for Ubig<S> {
40 #[inline]
41 fn signum(&self) -> Sign {
42 if self.is_not_zero() { Sign::Positive } else { Sign::Zero }
44 }
45
46 #[inline]
47 fn is_positive(&self) -> bool {
48 self.is_not_zero()
49 }
50
51 #[inline]
52 fn is_negative(&self) -> bool {
53 false
54 }
55}
56
57impl<const S: usize> Signed for NonZeroUbig<S> {
58 fn signum(&self) -> Sign {
59 Sign::Positive
60 }
61
62 fn is_positive(&self) -> bool {
63 true
64 }
65
66 fn is_negative(&self) -> bool {
67 false
68 }
69}
70
71impl<const S: usize> Ord for NonZeroUbig<S> {
72 fn cmp(&self, other: &Self) -> Ordering {
73 cmp(&self.0, &other.0)
74 }
75}
76
77impl<const S: usize> Ord for Ubig<S> {
78 fn cmp(&self, other: &Self) -> Ordering {
79 cmp(&self.0, &other.0)
80 }
81}
82
83impl<const S: usize> PartialOrd for NonZeroUbig<S> {
84 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
85 Some(self.cmp(other))
86 }
87}
88
89impl<const S: usize> PartialOrd for Ubig<S> {
90 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
91 Some(self.cmp(other))
92 }
93}
94
95#[must_use]
106#[inline]
107pub fn cmp(left: &[usize], right: &[usize]) -> Ordering {
108 debug_assert!(is_well_formed(left));
109 debug_assert!(is_well_formed(right));
110
111 if left.len() != right.len() {
113 return left.len().cmp(&right.len());
114 }
115
116 for (left_word, right_word) in left.iter().zip(right.iter()).rev() {
117 match left_word.cmp(right_word) {
118 Ordering::Less => return Ordering::Less,
119 Ordering::Equal => {}
120 Ordering::Greater => return Ordering::Greater,
121 }
122 }
123
124 Ordering::Equal
125}
126
127#[cfg(test)]
128mod test {
129 use std::cmp::Ordering;
130
131 use crate::{NonZero, Sign, Signed, Ubig};
132 use crate::integer::big::NonZeroUbig;
133 use crate::integer::big::properties::cmp;
134
135 #[test]
141 fn test_signed_zero_is_not_positive() {
142 let zero = Ubig::<8>::from(0_u128);
143 assert!(!zero.is_not_zero());
144 assert_eq!(zero.signum(), Sign::Zero);
145 assert!(!zero.is_positive());
146 assert!(!zero.is_negative());
147
148 for value in [1_u128, 2, u64::MAX as u128, u128::MAX] {
149 let big = Ubig::<8>::from(value);
150 assert!(big.is_not_zero(), "{value}");
151 assert_eq!(big.signum(), Sign::Positive, "{value}");
152 assert!(big.is_positive(), "{value}");
153 assert!(!big.is_negative(), "{value}");
154 }
155 }
156
157 #[test]
159 fn test_non_zero_signed_is_positive() {
160 for value in [1_u128, 2, u128::MAX] {
161 let big = NonZeroUbig::<8>::new_u128(value).unwrap();
162 assert_eq!(big.signum(), Sign::Positive, "{value}");
163 assert!(big.is_positive(), "{value}");
164 }
165 }
166
167 #[test]
172 fn test_cmp() {
173 assert_eq!(cmp(&[], &[]), Ordering::Equal);
174 assert_eq!(cmp(&[], &[1]), Ordering::Less);
175 assert_eq!(cmp(&[1], &[]), Ordering::Greater);
176
177 assert_eq!(cmp(&[1], &[usize::MAX, 1]), Ordering::Less);
179 assert_eq!(cmp(&[usize::MAX, 1], &[1]), Ordering::Greater);
180
181 assert_eq!(cmp(&[7], &[7]), Ordering::Equal);
182 assert_eq!(cmp(&[6], &[7]), Ordering::Less);
183 assert_eq!(cmp(&[7], &[6]), Ordering::Greater);
184
185 assert_eq!(cmp(&[usize::MAX, 1], &[0, 2]), Ordering::Less);
187 assert_eq!(cmp(&[0, 2], &[usize::MAX, 1]), Ordering::Greater);
188
189 assert_eq!(cmp(&[1, 2, 3], &[2, 2, 3]), Ordering::Less);
191 assert_eq!(cmp(&[3, 2, 3], &[3, 1, 3]), Ordering::Greater);
192 assert_eq!(cmp(&[1, 2, 3], &[1, 2, 3]), Ordering::Equal);
193 }
194}