1#[cfg(test)]
2use super::*;
3use paste::paste;
4
5#[cfg(test)]
6use num_bigint::{BigInt, Sign};
7
8use radix_common::*;
9#[allow(unused_imports)] use sbor::rust::cmp::Ordering;
11
12test_impl! {I192, I256, I320, I384, I448, I512, I768}
13test_impl! {U192, U256, U320, U384, U448, U512, U768}
14
15test_add_all! {
16 (I192, I256, I320, I384, I448, I512, I768,
17 U192, U256, U320, U384, U448, U512, U768),
18 (I192, I256, I320, I384, I448, I512, I768,
19 U192, U256, U320, U384, U448, U512, U768)
20}
21
22test_signed! { I192, I256, I320, I384, I448, I512, I768 }
23test_unsigned! { U192, U256, U320, U384, U448, U512, U768 }
24
25test_from_all_types_safe_builtin! {I192, (i8, i16, i32, i64, i128)}
26test_from_all_types_safe_builtin! {I192, (u8, u16, u32, u64, u128)}
27
28test_from_all_types_safe_builtin! {I256, (i8, i16, i32, i64, i128)}
29test_from_all_types_safe_builtin! {I256, (u8, u16, u32, u64, u128)}
30
31test_from_all_types_safe_builtin! {I320, (i8, i16, i32, i64, i128)}
32test_from_all_types_safe_builtin! {I320, (u8, u16, u32, u64, u128)}
33
34test_from_all_types_safe_builtin! {I384, (i8, i16, i32, i64, i128)}
35test_from_all_types_safe_builtin! {I384, (u8, u16, u32, u64, u128)}
36
37test_from_all_types_safe_builtin! {I448, (i8, i16, i32, i64, i128)}
38test_from_all_types_safe_builtin! {I448, (u8, u16, u32, u64, u128)}
39
40test_from_all_types_safe_builtin! {I512, (i8, i16, i32, i64, i128)}
41test_from_all_types_safe_builtin! {I512, (u8, u16, u32, u64, u128)}
42
43test_from_all_types_safe_builtin! {I768, (i8, i16, i32, i64, i128)}
44test_from_all_types_safe_builtin! {I768, (u8, u16, u32, u64, u128)}
45
46test_from_all_types_safe_builtin! {U192, (u8, u16, u32, u64, u128)}
47test_from_all_types_safe_builtin! {U256, (u8, u16, u32, u64, u128)}
48test_from_all_types_safe_builtin! {U320, (u8, u16, u32, u64, u128)}
49test_from_all_types_safe_builtin! {U384, (u8, u16, u32, u64, u128)}
50test_from_all_types_safe_builtin! {U448, (u8, u16, u32, u64, u128)}
51test_from_all_types_safe_builtin! {U512, (u8, u16, u32, u64, u128)}
52test_from_all_types_safe_builtin! {U768, (u8, u16, u32, u64, u128)}
53
54test_from_all_types_safe_safe! {I192, (I256, I320, I384, I448, I512, I768)}
55test_from_all_types_safe_safe! {I256, (I192, I320, I384, I448, I512, I768)}
56test_from_all_types_safe_safe! {I320, (I192, I256, I384, I448, I512, I768)}
57test_from_all_types_safe_safe! {I384, (I192, I256, I320, I448, I512, I768)}
58test_from_all_types_safe_safe! {I448, (I192, I256, I320, I384, I512, I768)}
59test_from_all_types_safe_safe! {I512, (I192, I256, I320, I384, I448, I768)}
60test_from_all_types_safe_safe! {I768, (I192, I256, I320, I384, I448, I512)}
61
62test_from_all_types_safe_safe! {U192, (U256, U320, U384, U448, U512, U768)}
63test_from_all_types_safe_safe! {U256, (U192, U320, U384, U448, U512, U768)}
64test_from_all_types_safe_safe! {U320, (U192, U256, U384, U448, U512, U768)}
65test_from_all_types_safe_safe! {U384, (U192, U256, U320, U448, U512, U768)}
66test_from_all_types_safe_safe! {U448, (U192, U256, U320, U384, U512, U768)}
67test_from_all_types_safe_safe! {U512, (U192, U256, U320, U384, U448, U768)}
68test_from_all_types_safe_safe! {U768, (U192, U256, U320, U384, U448, U512)}
69
70#[cfg(test)]
71macro_rules! assert_int_size {
72 ($($bits: literal $t: ident),*) => {
73 $(
74 assert_eq!($t::BITS, $bits);
75 )*
76 }
77}
78
79#[test]
80fn test_int_size() {
81 assert_int_size! {
82 192 I192,
83 256 I256,
84 320 I320,
85 384 I384,
86 448 I448,
87 512 I512,
88 768 I768,
89 192 U192,
90 256 U256,
91 320 U320,
92 384 U384,
93 448 U448,
94 512 U512,
95 768 U768
96 }
97}
98
99#[cfg(test)]
100macro_rules! test_bnums {
101 ($($t: ident),*) => {
102 paste! {
103 $(
104 #[test]
105 fn [<test_ $t:lower _add>] () {
106 assert_eq!((<$t>::ONE + <$t>::ONE).to_string(), "2");
107 assert_eq!(<$t>::from(17_u32) + <$t>::from(31_u32), <$t>::from(48_u32));
108 let mut bnum = <$t>::ONE;
109 bnum += <$t>::from_str("101").unwrap();
110 assert_eq!(bnum, <$t>::from_str("102").unwrap());
111
112 if <$t>::MIN < <$t>::ZERO {
113 let mut bnum = <$t>::MAX;
114 bnum += <$t>::try_from(-1_i32).unwrap();
115 assert_eq!(bnum, <$t>::MAX - <$t>::ONE);
116
117 assert_eq!(<$t>::MIN + <$t>::MAX, <$t>::ZERO - <$t>::ONE);
118 }
119 }
120
121 #[test]
122 fn [< test_ $t:lower _sub >]() {
123 assert_eq!(<$t>::ONE - <$t>::ONE, <$t>::ZERO);
124
125 if <$t>::MIN < <$t>::ZERO {
126 assert_eq!(<$t>::from(17_u32) - <$t>::from(31_u32), <$t>::try_from(-14).unwrap());
127 let mut bnum = <$t>::from(101_u32);
128 bnum -= <$t>::from_str("102").unwrap();
129 assert_eq!(bnum, <$t>::from_str("-1").unwrap());
130 }
131
132 let mut bnum = <$t>::MAX;
133 bnum -= <$t>::ONE;
134 assert_eq!(bnum, <$t>::MAX - <$t>::ONE);
135 }
136
137 #[test]
138 #[should_panic(expected = "Overflow")]
139 fn [<test_ $t:lower _add_overflow_panic_1>] () {
140 let mut bnum = <$t>::MAX;
141 bnum += <$t>::from(1_u32);
142 }
143
144 #[test]
145 #[should_panic(expected = "Overflow")]
146 fn [< test_ $t:lower _sub_overflow_panic_2 >]() {
147 let mut bnum = <$t>::MIN;
148 bnum -= <$t>::ONE;
149 }
150
151 #[test]
152 fn [< test_ $t:lower _mul >]() {
153 assert_eq!(<$t>::from(4_u32) * <$t>::from(5_u32), <$t>::from(20_u32));
154 let mut bnum = <$t>::from(12387_u32);
155 bnum *= <$t>::from_str("1203203031").unwrap();
156 assert_eq!(bnum, <$t>::from(14904075944997_u128));
157
158 if <$t>::MIN < <$t>::ZERO {
159 let mut bnum = <$t>::from(12387_u32);
160 bnum *= <$t>::from_str("-1203203031").unwrap();
161 assert_eq!(bnum, <$t>::try_from(-14904075944997_i128).unwrap());
162 }
163 }
164
165 #[test]
166 #[should_panic(expected = "Overflow")]
167 fn [< test_ $t:lower _mul_overflow_panic_1 >] () {
168 let mut bnum = <$t>::MAX;
169 bnum *= <$t>::from(2_u32);
170 }
171
172
173 #[test]
174 fn [< test_ $t:lower _pow >](){
175 assert_eq!(<$t>::from(3_u32).pow(3), <$t>::from(27_u32));
176
177 assert_eq!(
178 <$t>::from(153_u32).pow(20),
179 <$t>::from_str("49411565790213547262766437937260727785410401").unwrap()
180 );
181 assert_eq!(
182 <$t>::from(153_u32).pow(25),
183 <$t>::from_str("4142721807044360524568533828494071080154747151557663193").unwrap()
184 );
185 }
186
187 #[test]
188 #[should_panic(expected = "Overflow")]
189 fn [< test_ $t:lower _pow_overflow_panic_1 >]() {
190 if <$t>::BITS == 192 {
191 let _ = <$t>::from(153_u32).pow(40);
192 } else if <$t>::BITS == 256 {
193 let _ = <$t>::from(153_u32).pow(40);
194 } else if <$t>::BITS == 320 {
195 let _ = <$t>::from(153_u32).pow(60);
196 } else if <$t>::BITS == 384 {
197 let _ = <$t>::from(153_u32).pow(60);
198 } else if <$t>::BITS == 448 {
199 let _ = <$t>::from(153_u32).pow(70);
200 } else if <$t>::BITS == 512 {
201 let _ = <$t>::from(153_u32).pow(80);
202 } else if <$t>::BITS == 768 {
203 let _ = <$t>::from(153_u32).pow(120);
204 } else {
205 panic!("Unknown bits size {}", <$t>::BITS);
206 }
207 }
208
209 #[test]
210 fn [< test_ $t:lower _root >]() {
211 assert_eq!(<$t>::from(9_u32).sqrt(), <$t>::from(3_u32));
212 assert_eq!(<$t>::from(27_u32).cbrt(), <$t>::from(3_u32));
213
214 assert_eq!(<$t>::from(9_u32).nth_root(2), <$t>::from(3_u32));
215 assert_eq!(<$t>::from(27_u32).nth_root(3), <$t>::from(3_u32));
216 assert_eq!(<$t>::from(14966675814359580587845230627_u128).nth_root(13), <$t>::from(147_u32));
217 assert_eq!(
218 <$t>::from_str("290437112829027226192310037731274304321654649956335616").unwrap().nth_root(17),
219 <$t>::from_str("1396").unwrap()
220 );
221
222 if <$t>::MIN < <$t>::ZERO {
223 assert_eq!(<$t>::try_from(-27).unwrap().nth_root(3), <$t>::try_from(-3).unwrap());
224 assert_eq!(<$t>::try_from(-14966675814359580587845230627_i128).unwrap().nth_root(13), <$t>::try_from(-147).unwrap());
225 }
226 }
227
228 #[test]
229 fn [< test_ $t:lower _to_string >]() {
230 assert_eq!(<$t>::ONE.to_string(), "1");
231 assert_eq!(<$t>::ZERO.to_string(), "0");
232 assert_eq!(<$t>::from_str("0").unwrap(), <$t>::ZERO);
233
234 if <$t>::MIN < <$t>::ZERO {
235 assert_eq!(<$t>::try_from(-1).unwrap().to_string(), "-1");
236
237 assert_eq!(<$t>::from_str("-1").unwrap(), <$t>::try_from(-1).unwrap());
238 }
239 }
240
241 #[test]
242 fn [< test_ $t:lower _to_primitive_ints >] () {
243 assert_eq!(<$t>::from_i8(1).unwrap(), <$t>::ONE);
244 assert_eq!(<$t>::try_from(21).unwrap().to_string(), "21");
245 assert_eq!(<$t>::from(21_u8).to_string(), "21");
246
247 let bnum: $t = 21_u32.into();
248 assert_eq!(bnum.to_string(), 21.to_string());
249
250 let i: i128 = <$t>::from(21_u8).try_into().unwrap();
251 assert_eq!(i, 21_i128);
252
253 let val = u8::try_from(<$t>::from(300_u32)).unwrap_err();
254 assert_eq!(val, [< Parse $t Error >]::Overflow);
255
256 if <$t>::MIN < <$t>::ZERO {
257 let val = u8::try_from(<$t>::try_from(-300_i32).unwrap()).unwrap_err();
258 assert_eq!(val, [< Parse $t Error >]::Overflow);
259 }
260 }
261
262 #[test]
263 #[should_panic(expected = "Err")]
264 fn [< test_ $t:lower _from_string_panic_1 >]() {
265 assert_eq!(<$t>::from_str("0x01").unwrap(), <$t>::try_from(-1).unwrap());
266 }
267
268 #[test]
269 #[should_panic(expected = "Overflow")]
270 fn [< test_ $t:lower _to_u128_panic >]() {
271 if <$t>::MIN < <$t>::ZERO {
272 let _u: u128 = <$t>::try_from(-21).unwrap().try_into().unwrap();
273 } else {
274 let _u: u128 = <$t>::from_str("290437112829027226192310037731274304321654649956335616").unwrap().try_into().unwrap();
275 }
276 }
277 #[test]
278 #[should_panic(expected = "Overflow")]
279 fn [< test_ $t:lower _to_i8_panic >]() {
280 let _i: i8 = <$t>::try_from(-260).unwrap().try_into().unwrap();
281 }
282
283 #[test]
284 #[should_panic(expected = "Overflow")]
285 fn [< test_ $t:lower _u16_panic >]() {
286 let _i: u16 = <$t>::from(123123123_u32).try_into().unwrap();
287 }
288
289 )*
290 }
291 }
292}
293
294#[cfg(test)]
295test_bnums! { I192, I256, I320, I384, I448, I512, I768 }
296#[cfg(test)]
297test_bnums! { U192, U256, U320, U384, U448, U512, U768 }
298
299#[cfg(test)]
300macro_rules! test_bnums_signed {
301 ($($t: ident),*) => {
302 paste! {
303 $(
304 #[test]
305 #[should_panic(expected = "Overflow")]
306 fn [< test_ $t:lower _mul_overflow_panic_2 >] () {
307 let bnum = <$t>::MIN;
308 let _m = bnum.mul(<$t>::from(2));
309 }
310
311 )*
312 }
313 }
314}
315#[cfg(test)]
316test_bnums_signed! { I192, I256, I320, I384, I448, I512, I768 }
317
318#[test]
319#[should_panic(expected = "Err")]
320fn test_string_to_bnum_panic_2() {
321 assert_eq!(
322 I256::MAX,
323 I256::from_str(
324 "578960446186580977117854925043439539266349923328202820197287920039565648199670"
325 )
326 .unwrap()
327 );
328}
329
330macro_rules! test_to_from_bigint {
331 ($($t: ident),*) => {
332 paste!{
333 $(
334 #[test]
335 fn [<test_to_from_bigint_ $t:lower>]() {
336 assert_eq!($t::try_from(BigInt::from(147)).unwrap(), $t::from(147_u32));
337
338 assert_eq!(
339 $t::try_from(BigInt::from(1470198230918_i128)).unwrap(),
340 $t::from(1470198230918_u128)
341 );
342
343 let big = BigInt::from($t::MAX) + BigInt::from(1);
344 let err = $t::try_from(big).unwrap_err();
345 assert_eq!(err, [<Parse $t Error>]::Overflow);
346
347 assert_eq!(BigInt::try_from($t::from(123_u32)).unwrap(), BigInt::from(123));
348 assert_eq!(BigInt::from($t::ONE), BigInt::from(1));
349
350 assert_eq!(
351 BigInt::from($t::MAX),
352 BigInt::from_str(
353 &$t::MAX.to_string()
354 )
355 .unwrap()
356 );
357
358 assert_eq!(
359 BigInt::from($t::MIN),
360 BigInt::from_str(
361 &$t::MIN.to_string()
362 )
363 .unwrap()
364 );
365
366 if $t::MIN != $t::ZERO {
368 assert_eq!($t::try_from(BigInt::from(-147)).unwrap(), $t::try_from(-147).unwrap());
369 assert_eq!(
370 $t::try_from(BigInt::from(-1470198230918_i128)).unwrap(),
371 $t::try_from(-1470198230918_i128).unwrap()
372 );
373 let big = BigInt::from($t::MIN) - BigInt::from(1);
374 let err = $t::try_from(big).unwrap_err();
375 assert_eq!(err, [<Parse $t Error>]::Overflow);
376 }
377 }
378 )*
379 }
380 }
381}
382test_to_from_bigint! { I192, I256, I320, I384, I448, I512, I768 }
383test_to_from_bigint! { U192, U256, U320, U384, U448, U512, U768 }
384
385#[test]
386fn test_bnum_to_bnum() {
387 let a = I192::from(1);
388 let b = U192::try_from(a).unwrap();
389 assert_eq!(b, U192::ONE);
390
391 let a = I256::from(1);
392 let b = U256::try_from(a).unwrap();
393 assert_eq!(b, U256::ONE);
394
395 let a = I256::from(-123);
396 let b = I512::from(a);
397 assert_eq!(a.to_string(), b.to_string());
398
399 let a = I256::MAX;
400 let b = U256::try_from(a).unwrap();
401 assert_eq!(a.to_string(), b.to_string());
402
403 let a = I256::MIN;
404 let b = I512::from(a);
405 assert_eq!(a.to_string(), b.to_string());
406
407 let a = U256::MAX;
408 let b = I512::from(a);
409 assert_eq!(a.to_string(), b.to_string());
410
411 let a = U256::MAX;
412 let b = I384::from(a);
413 assert_eq!(a.to_string(), b.to_string());
414}
415
416#[test]
417fn test_bnum_to_bnum_errors() {
418 let i512 = I512::MIN;
419 let err = I192::try_from(i512).unwrap_err();
420 assert_eq!(err, ParseI192Error::Overflow);
421
422 let i512 = I512::MIN;
423 let err = I256::try_from(i512).unwrap_err();
424 assert_eq!(err, ParseI256Error::Overflow);
425
426 let i256_str = I256::MAX.to_string();
428 let i512 = I512::from_str(&i256_str).unwrap() + I512::ONE;
429 let err = I256::try_from(i512).unwrap_err();
430 assert_eq!(err, ParseI256Error::Overflow);
431
432 let i256_str = I256::MIN.to_string();
434 let i512 = I512::from_str(&i256_str).unwrap() - I512::ONE;
435 let err = I256::try_from(i512).unwrap_err();
436 assert_eq!(err, ParseI256Error::Overflow);
437
438 let u256 = U256::MAX;
439 let err = I256::try_from(u256).unwrap_err();
440 assert_eq!(err, ParseI256Error::Overflow);
441
442 let i512_str = I512::MAX.to_string();
443 let u512 = U512::from_str(&i512_str).unwrap() + U512::ONE;
444 let err = U256::try_from(u512).unwrap_err();
445 assert_eq!(err, ParseU256Error::Overflow);
446
447 let u512 = U512::MAX;
448 let err = I256::try_from(u512).unwrap_err();
449 assert_eq!(err, ParseI256Error::Overflow);
450
451 let a = U256::MAX;
452 let b = I256::try_from(a).unwrap_err();
453 assert_eq!(b, ParseI256Error::Overflow);
454
455 let i512 = -I512::ONE;
456 let err = U256::try_from(i512).unwrap_err();
457 assert_eq!(err, ParseU256Error::NegativeToUnsigned);
458
459 let i256 = I256::from(-123);
460 let err = U512::try_from(i256).unwrap_err();
461 assert_eq!(err, ParseU512Error::NegativeToUnsigned);
462
463 let i384 = I384::MAX;
464 let err = U256::try_from(i384).unwrap_err();
465 assert_eq!(err, ParseU256Error::Overflow);
466}