crypto_bigint/int/
from.rs1use crate::{CtOption, I64, I128, Int, Limb, Uint, Word};
4
5macro_rules! check_limbs {
6 ($limbs:expr) => {
7 const {
8 assert!($limbs >= 1, "number of limbs must be greater than zero");
9 }
10 };
11}
12
13#[allow(clippy::cast_sign_loss)]
14impl<const LIMBS: usize> Int<LIMBS> {
15 #[inline]
18 #[must_use]
19 pub const fn from_i8(n: i8) -> Self {
20 check_limbs!(LIMBS);
21 Uint::new([Limb(n as Word)]).as_int().resize()
22 }
23
24 #[inline]
27 #[must_use]
28 pub const fn from_i16(n: i16) -> Self {
29 check_limbs!(LIMBS);
30 Uint::new([Limb(n as Word)]).as_int().resize()
31 }
32
33 #[inline]
36 #[must_use]
37 pub const fn from_i32(n: i32) -> Self {
38 check_limbs!(LIMBS);
39 Uint::new([Limb(n as Word)]).as_int().resize()
40 }
41
42 cpubits::cpubits! {
43 32 => {
44 #[inline]
47 pub const fn from_i64(n: i64) -> Self {
48 check_limbs!(LIMBS);
49 Uint::<{ I64::LIMBS }>::from_u64(n as u64).as_int().resize()
50 }
51 }
52 64 => {
53 #[inline]
56 #[must_use]
57 pub const fn from_i64(n: i64) -> Self {
58 check_limbs!(LIMBS);
59 Uint::new([Limb(n as Word)]).as_int().resize()
60 }
61 }
62 }
63
64 #[inline]
67 #[must_use]
68 pub const fn from_i128(n: i128) -> Self {
69 Uint::<{ I128::LIMBS }>::from_u128(n as u128)
70 .as_int()
71 .resize()
72 }
73
74 #[inline]
77 pub(super) const fn from_uint_opt(opt: CtOption<Uint<LIMBS>>) -> CtOption<Self> {
78 CtOption::new(*opt.as_inner_unchecked().as_int(), opt.is_some())
79 }
80}
81
82impl<const LIMBS: usize> From<i8> for Int<LIMBS> {
83 #[inline]
84 fn from(n: i8) -> Self {
85 const {
86 debug_assert!(LIMBS > 0, "limbs must be non-zero");
87 }
88 Self::from_i8(n)
89 }
90}
91
92impl<const LIMBS: usize> From<i16> for Int<LIMBS> {
93 #[inline]
94 fn from(n: i16) -> Self {
95 const {
96 debug_assert!(LIMBS > 0, "limbs must be non-zero");
97 }
98 Self::from_i16(n)
99 }
100}
101
102impl<const LIMBS: usize> From<i32> for Int<LIMBS> {
103 #[inline]
104 fn from(n: i32) -> Self {
105 const {
106 debug_assert!(LIMBS > 0, "limbs must be non-zero");
107 }
108 Self::from_i32(n)
109 }
110}
111
112impl<const LIMBS: usize> From<i64> for Int<LIMBS> {
113 #[inline]
114 fn from(n: i64) -> Self {
115 #[allow(clippy::integer_division_remainder_used, reason = "const/debug")]
116 const {
117 debug_assert!(LIMBS >= 8 / Limb::BYTES, "not enough limbs");
118 }
119 Self::from_i64(n)
120 }
121}
122
123impl<const LIMBS: usize> From<i128> for Int<LIMBS> {
124 #[inline]
125 fn from(n: i128) -> Self {
126 #[allow(clippy::integer_division_remainder_used, reason = "const/debug")]
127 const {
128 debug_assert!(LIMBS >= 16 / Limb::BYTES, "not enough limbs");
129 }
130 Self::from_i128(n)
131 }
132}
133
134impl From<I64> for i64 {
135 #[inline]
136 #[allow(clippy::cast_possible_wrap)]
137 fn from(n: I64) -> i64 {
138 u64::from(n.0) as i64
139 }
140}
141
142impl From<I128> for i128 {
143 #[inline]
144 #[allow(clippy::cast_possible_wrap)]
145 fn from(n: I128) -> i128 {
146 u128::from(n.0) as i128
147 }
148}
149
150impl<const LIMBS: usize, const LIMBS2: usize> From<&Int<LIMBS>> for Int<LIMBS2> {
151 #[inline]
152 fn from(num: &Int<LIMBS>) -> Int<LIMBS2> {
153 num.resize()
154 }
155}
156
157#[cfg(test)]
158mod tests {
159 use crate::{I128, Limb};
160
161 cpubits::cpubits! {
162 32 => { use crate::I64 as IntEx; }
163 64 => { use crate::I128 as IntEx; }
164 }
165
166 #[test]
167 fn from_i8() {
168 let n = IntEx::from(42i8);
169 assert_eq!(n.as_limbs(), &[Limb(42), Limb(0)]);
170 let n = IntEx::from(-42i8);
171 assert_eq!(n.as_limbs(), &[Limb::MAX - Limb::from(41u32), Limb::MAX]);
172 }
173
174 #[test]
175 fn from_i16() {
176 let n = IntEx::from(42i16);
177 assert_eq!(n.as_limbs(), &[Limb(42), Limb(0)]);
178 let n = IntEx::from(-42i16);
179 assert_eq!(n.as_limbs(), &[Limb::MAX - Limb::from(41u32), Limb::MAX]);
180 }
181
182 #[test]
183 fn from_i32() {
184 let n = IntEx::from(42i32);
185 assert_eq!(n.as_limbs(), &[Limb(42), Limb(0)]);
186 let n = IntEx::from(-42i32);
187 assert_eq!(n.as_limbs(), &[Limb::MAX - Limb::from(41u32), Limb::MAX]);
188 }
189
190 #[test]
191 fn from_i64() {
192 let n = IntEx::from(42i64);
193 assert_eq!(n.as_limbs(), &[Limb(42), Limb(0)]);
194 let n = IntEx::from(-42i64);
195 assert_eq!(n.as_limbs(), &[Limb::MAX - Limb::from(41u32), Limb::MAX]);
196 }
197
198 #[test]
199 fn from_i128() {
200 let n = I128::from(42i128);
201 assert_eq!(&n.as_limbs()[..2], &[Limb(42), Limb(0)]);
202 assert_eq!(i128::from(n), 42i128);
203 let n = I128::from(-42i128);
204 assert_eq!(&n.as_limbs()[..2], &[Limb::MAX - Limb(41), Limb::MAX]);
205 assert_eq!(i128::from(n), -42i128);
206 }
207}