crypto_bigint/int/
sign.rs1use crate::{ConstChoice, ConstCtOption, Int, Uint, Word};
2use num_traits::ConstZero;
3
4impl<const LIMBS: usize> Int<LIMBS> {
5 const fn most_significant_word(&self) -> Word {
10 if Self::LIMBS == 0 {
11 Word::ZERO
12 } else {
13 self.0.to_words()[LIMBS - 1]
14 }
15 }
16
17 pub const fn new_from_abs_sign(
20 abs: Uint<LIMBS>,
21 is_negative: ConstChoice,
22 ) -> ConstCtOption<Self> {
23 let magnitude = Self(abs).wrapping_neg_if(is_negative);
24 let fits = Uint::lte(&abs, &Int::MAX.0).or(is_negative.and(Uint::eq(&abs, &Int::MIN.0)));
25 ConstCtOption::new(magnitude, fits)
26 }
27
28 pub const fn is_negative(&self) -> ConstChoice {
30 ConstChoice::from_word_msb(self.most_significant_word())
31 }
32
33 pub const fn is_positive(&self) -> ConstChoice {
35 self.is_negative().not().and(self.is_nonzero())
36 }
37
38 pub const fn abs_sign(&self) -> (Uint<LIMBS>, ConstChoice) {
40 let sign = self.is_negative();
41 let abs = self.wrapping_neg_if(sign);
43 (abs.0, sign)
44 }
45
46 pub const fn abs(&self) -> Uint<LIMBS> {
48 self.abs_sign().0
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55 use crate::I128;
56
57 #[test]
58 fn is_negative() {
59 assert_eq!(I128::MIN.is_negative(), ConstChoice::TRUE);
60 assert_eq!(I128::MINUS_ONE.is_negative(), ConstChoice::TRUE);
61 assert_eq!(I128::ZERO.is_negative(), ConstChoice::FALSE);
62 assert_eq!(I128::ONE.is_negative(), ConstChoice::FALSE);
63 assert_eq!(I128::MAX.is_negative(), ConstChoice::FALSE);
64
65 let random_negative = I128::from_be_hex("91113333555577779999BBBBDDDDFFFF");
66 assert_eq!(random_negative.is_negative(), ConstChoice::TRUE);
67
68 let random_positive = I128::from_be_hex("71113333555577779999BBBBDDDDFFFF");
69 assert_eq!(random_positive.is_negative(), ConstChoice::FALSE);
70 }
71
72 #[test]
73 fn is_positive() {
74 assert_eq!(I128::MIN.is_positive(), ConstChoice::FALSE);
75 assert_eq!(I128::MINUS_ONE.is_positive(), ConstChoice::FALSE);
76 assert_eq!(I128::ZERO.is_positive(), ConstChoice::FALSE);
77 assert_eq!(I128::ONE.is_positive(), ConstChoice::TRUE);
78 assert_eq!(I128::MAX.is_positive(), ConstChoice::TRUE);
79
80 let random_negative = I128::from_be_hex("deadbeefcafebabedeadbeefcafebabe");
81 assert_eq!(random_negative.is_positive(), ConstChoice::FALSE);
82
83 let random_positive = I128::from_be_hex("0badc0dedeadc0decafebabedeadcafe");
84 assert_eq!(random_positive.is_positive(), ConstChoice::TRUE);
85 }
86}