alloy_primitives/signed/
utils.rs
1use crate::signed::Signed;
2use ruint::Uint;
3
4#[inline]
6#[track_caller]
7pub(super) const fn handle_overflow<T: Copy>((result, overflow): (T, bool)) -> T {
8 debug_assert!(!overflow, "overflow");
9 result
10}
11
12#[inline]
14pub(super) fn twos_complement<const BITS: usize, const LIMBS: usize>(
15 u: Uint<BITS, LIMBS>,
16) -> Uint<BITS, LIMBS> {
17 if BITS == 0 {
18 return u;
19 }
20 (!u).overflowing_add(Uint::<BITS, LIMBS>::from(1)).0
21}
22
23#[inline]
25pub(super) const fn const_eq<const BITS: usize, const LIMBS: usize>(
26 left: &Signed<BITS, LIMBS>,
27 right: &Signed<BITS, LIMBS>,
28) -> bool {
29 if BITS == 0 {
30 return true;
31 }
32
33 let mut i = 0;
34 let llimbs = left.0.as_limbs();
35 let rlimbs = right.0.as_limbs();
36 while i < LIMBS {
37 if llimbs[i] != rlimbs[i] {
38 return false;
39 }
40 i += 1;
41 }
42 true
43}
44
45pub(super) const fn max<const BITS: usize, const LIMBS: usize>() -> Signed<BITS, LIMBS> {
47 if LIMBS == 0 {
48 return zero();
49 }
50
51 let mut limbs = [u64::MAX; LIMBS];
52 limbs[LIMBS - 1] &= Signed::<BITS, LIMBS>::MASK; limbs[LIMBS - 1] &= !Signed::<BITS, LIMBS>::SIGN_BIT; Signed(Uint::from_limbs(limbs))
55}
56
57pub(super) const fn min<const BITS: usize, const LIMBS: usize>() -> Signed<BITS, LIMBS> {
58 if LIMBS == 0 {
59 return zero();
60 }
61
62 let mut limbs = [0; LIMBS];
63 limbs[LIMBS - 1] = Signed::<BITS, LIMBS>::SIGN_BIT;
64 Signed(Uint::from_limbs(limbs))
65}
66
67pub(super) const fn zero<const BITS: usize, const LIMBS: usize>() -> Signed<BITS, LIMBS> {
68 let limbs = [0; LIMBS];
69 Signed(Uint::from_limbs(limbs))
70}
71
72pub(super) const fn one<const BITS: usize, const LIMBS: usize>() -> Signed<BITS, LIMBS> {
73 if LIMBS == 0 {
74 return zero();
75 }
76
77 let mut limbs = [0; LIMBS];
78 limbs[0] = 1;
79 Signed(Uint::from_limbs(limbs))
80}
81
82pub(super) const fn sign_bit(bits: usize) -> u64 {
84 if bits == 0 {
85 return 0;
86 }
87 let bits = bits % 64;
88 if bits == 0 {
89 1 << 63
90 } else {
91 1 << (bits - 1)
92 }
93}