mirror of
				https://gitlab.com/artofrev/smallint.git
				synced 2025-10-31 06:51:12 -04:00 
			
		
		
		
	impl BitAnd for BigUint, add lots of tests
This commit is contained in:
		
							parent
							
								
									70bc33217c
								
							
						
					
					
						commit
						7702b67f07
					
				| @ -16,3 +16,7 @@ num-bigint = { version = "0.4.3", optional = true } | ||||
| 
 | ||||
| [dev-dependencies] | ||||
| num-bigint = { version = "0.4.3" } | ||||
| 
 | ||||
| 
 | ||||
| [profile.test] | ||||
| opt-level = 2 | ||||
|  | ||||
							
								
								
									
										130
									
								
								src/logic.rs
									
									
									
									
									
								
							
							
						
						
									
										130
									
								
								src/logic.rs
									
									
									
									
									
								
							| @ -1,3 +1,4 @@ | ||||
| use crate::ops::{add_two_slices, sub_two_slices}; | ||||
| use crate::smallint::{SmallIntType, SmallUintType}; | ||||
| use crate::{SmallInt, SmallUint}; | ||||
| use core::cmp::Ordering; | ||||
| @ -97,13 +98,20 @@ macro_rules! logic_op { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| macro_rules! inline_heap_to_inline { | ||||
|     ($fun:ident, $typ:ident, $typ_inner:ident, $typ_inline:ident; $i:ident, $slice:ident) => { | ||||
| macro_rules! heap_to_inline { | ||||
|     ($typ_inline:ident; $slice:ident) => { | ||||
|         let mut j = 0; | ||||
|         for i in 0..4 { | ||||
|             j <<= 32; | ||||
|             j |= $slice[3 - i] as $typ_inline; | ||||
|         } | ||||
|         j | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| macro_rules! inline_heap_to_inline { | ||||
|     ($fun:ident, $typ:ident, $typ_inner:ident, $typ_inline:ident; $i:ident, $slice:ident) => { | ||||
|         let j = { heap_to_inline! { $typ_inline; $slice } }; | ||||
|         $typ($typ_inner::Inline($i.$fun(j))) | ||||
|     } | ||||
| } | ||||
| @ -128,7 +136,7 @@ macro_rules! inline_heap_to_heap { | ||||
| 
 | ||||
| 
 | ||||
| macro_rules! heap_heap_create_res_shortest { | ||||
|     ($fun:ident; $min:ident, $slice1:ident, $slice2:ident) => { | ||||
|     ($fun:ident; $slice1:ident, $slice2:ident, $min:ident) => { | ||||
|         let mut res = Vec::with_capacity($min); | ||||
|         for l in 0..$min { | ||||
|             res.push($slice1[l].$fun($slice2[l])); | ||||
| @ -152,10 +160,31 @@ macro_rules! heap_heap_create_res_longest { | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| macro_rules! heap_heap_return_heap_inner { | ||||
|     ($typ:ident, $typ_inner:ident; $res:ident) => { | ||||
|         let mut slice = ManuallyDrop::new($res); | ||||
|         $typ($typ_inner::Heap((slice.as_mut_ptr(), slice.len().try_into().unwrap()))) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| macro_rules! heap_heap_return_heap_inner_neg { | ||||
|     ($typ:ident, $typ_inner:ident; $res:ident) => { | ||||
|         let mut slice = ManuallyDrop::new($res); | ||||
|         $typ($typ_inner::Heap((slice.as_mut_ptr(), -isize::try_from(slice.len()).unwrap()))) | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| macro_rules! heap_heap_return_heap { | ||||
|     ($typ:ident, $typ_inner:ident; $res:ident) => { | ||||
|         let mut slice = ManuallyDrop::new($res.into_boxed_slice()); | ||||
|         $typ($typ_inner::Heap((slice.as_mut_ptr(), slice.len().try_into().unwrap()))) | ||||
|         let res = $res.into_boxed_slice(); | ||||
|         heap_heap_return_heap_inner! { $typ, $typ_inner; res } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| macro_rules! heap_heap_return_heap_neg { | ||||
|     ($typ:ident, $typ_inner:ident; $res:ident) => { | ||||
|         let res = $res.into_boxed_slice(); | ||||
|         heap_heap_return_heap_inner_neg! { $typ, $typ_inner; res } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -183,7 +212,7 @@ logic_op! { | ||||
|     BitAnd, BitAndAssign, SmallUint, SmallUintType, bitand, bitand_assign; | ||||
|     i, j, p, q, s, t, slice, slice1, slice2, min, res; | ||||
|     { inline_heap_to_inline! { bitand, SmallUint, SmallUintType, u128; i, slice } }, | ||||
|     { heap_heap_create_res_shortest! { bitand; min, slice1, slice2 } }, | ||||
|     { heap_heap_create_res_shortest! { bitand; slice1, slice2, min } }, | ||||
|     { heap_heap_return_any! { SmallUint, SmallUintType, u128; res } } | ||||
| } | ||||
| 
 | ||||
| @ -205,28 +234,101 @@ logic_op! { | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| fn bitor_two_slices(slice1: &[u32], slice2: &[u32]) -> Vec<u32> { | ||||
|     let mut result = if slice1.len() > slice2.len() { | ||||
|         slice1.to_vec() | ||||
|     } else { | ||||
|         slice2.to_vec() | ||||
|     }; | ||||
|     for l in 0..std::cmp::min(slice1.len(), slice2.len()) { | ||||
|         result[l] = slice1[l] | slice2[l]; | ||||
|     } | ||||
|     result | ||||
| } | ||||
| 
 | ||||
| fn bitand_two_slices_mixed_sign(positive: &[u32], negative: &[u32]) -> Vec<u32> { | ||||
|     // a & (-b) = (a | (b - 1)) + 1 - b
 | ||||
|     // 0 is not negative, so we can ignore it
 | ||||
|     let sub1 = sub_two_slices(negative, &[1]); | ||||
|     let or = bitor_two_slices(positive, &sub1); | ||||
|     let add = add_two_slices(&or, &[1]); | ||||
|     let sub2 = sub_two_slices(&add, negative); | ||||
|     sub2 | ||||
| } | ||||
| 
 | ||||
| logic_op! { | ||||
|     BitXor, BitXorAssign, SmallInt, SmallIntType, bitxor, bitxor_assign; | ||||
|     BitAnd, BitAndAssign, SmallInt, SmallIntType, bitand, bitand_assign; | ||||
|     i, j, p, q, s, t; | ||||
|     { | ||||
|         todo!() | ||||
|         let slice = unsafe { core::slice::from_raw_parts(p, s.unsigned_abs()) }; | ||||
|         match (i.cmp(&0), s.cmp(&0)) { | ||||
|             (Ordering::Equal, _) => SmallInt(SmallIntType::Inline(0)), | ||||
|             (Ordering::Greater, Ordering::Greater) => { | ||||
|                 let j = { heap_to_inline! { i128; slice } }; | ||||
|                 SmallInt(SmallIntType::Inline(i & j)) | ||||
|             }, | ||||
|             (Ordering::Greater, Ordering::Less) => { | ||||
|                 let j = { heap_to_inline! { i128; slice } }; | ||||
|                 SmallInt(SmallIntType::Inline(i & -j)) | ||||
|             }, | ||||
|             (Ordering::Less, Ordering::Greater) => { | ||||
|                 let mut res = <Box<[u32]>>::from(slice); | ||||
|                 let mut inline = i; | ||||
|                 for idx in 0..4 { | ||||
|                     res[idx] &= inline as u32; | ||||
|                     inline >>= 32; | ||||
|                 } | ||||
|                 heap_heap_return_heap_inner! { SmallInt, SmallIntType; res } | ||||
|             }, | ||||
|             (Ordering::Less, Ordering::Less) => { | ||||
|                 let mut res = <Box<[u32]>>::from(slice); | ||||
|                 let j = { heap_to_inline! { i128; slice } }; | ||||
|                 let lo = (i & j.wrapping_neg()).wrapping_neg(); | ||||
|                 let mut lo_remaining = lo; | ||||
|                 for idx in 0..4 { | ||||
|                     res[idx] = lo_remaining as u32; | ||||
|                     lo_remaining >>= 32; | ||||
|                 } | ||||
| 
 | ||||
|                 if lo == 0 && j != 0 { | ||||
|                     let res2 = add_two_slices(&res, &[0, 0, 0, 0, 1]); | ||||
|                     heap_heap_return_heap_neg! { SmallInt, SmallIntType; res2 } | ||||
|                 } else { | ||||
|                     heap_heap_return_heap_inner_neg! { SmallInt, SmallIntType; res } | ||||
|                 } | ||||
|             }, | ||||
|             (_, Ordering::Equal) => unreachable!("0 must be inline"), | ||||
|         } | ||||
|     }, | ||||
|     { | ||||
|         let slice1 = unsafe { core::slice::from_raw_parts(p, s.unsigned_abs()) }; | ||||
|         let slice2 = unsafe { core::slice::from_raw_parts(q, t as usize) }; | ||||
|         let slice2 = unsafe { core::slice::from_raw_parts(q, t.unsigned_abs()) }; | ||||
|         match (s.cmp(&0), t.cmp(&0)) { | ||||
|             (Ordering::Greater, Ordering::Greater) => { | ||||
|                 let min = std::cmp::min(slice1.len(), slice2.len()); | ||||
| 
 | ||||
|                 #[allow(unused_mut)] | ||||
|                 let mut res = { heap_heap_create_res_longest! { bitxor; slice1, slice2, min } }; | ||||
|                 let mut res = { heap_heap_create_res_shortest! { bitand; slice1, slice2, min } }; | ||||
| 
 | ||||
|                 heap_heap_return_any! { SmallInt, SmallIntType, i128; res } | ||||
|                 heap_heap_return_heap! { SmallInt, SmallIntType; res } | ||||
|             }, | ||||
|             (Ordering::Greater, Ordering::Less) => { | ||||
|                 let res = bitand_two_slices_mixed_sign(slice1, slice2); | ||||
|                 heap_heap_return_heap! { SmallInt, SmallIntType; res } | ||||
|             }, | ||||
|             (Ordering::Less, Ordering::Greater) => { | ||||
|                 let res = bitand_two_slices_mixed_sign(slice2, slice1); | ||||
|                 heap_heap_return_heap! { SmallInt, SmallIntType; res } | ||||
|             }, | ||||
|             (Ordering::Less, Ordering::Less) => { | ||||
|                 // (-a) & (-b) = -(((a-1) | (b-1)) + 1)
 | ||||
|                 // 0 is not negative, so we can ignore it
 | ||||
|                 let sub1 = sub_two_slices(slice1, &[1]); | ||||
|                 let sub2 = sub_two_slices(slice2, &[1]); | ||||
|                 let tmp = bitor_two_slices(&sub1, &sub2); | ||||
|                 let res = add_two_slices(&tmp, &[1]); | ||||
|                 heap_heap_return_heap_neg! { SmallInt, SmallIntType; res } | ||||
|             }, | ||||
|             (Ordering::Greater, Ordering::Less) => todo!(), | ||||
|             (Ordering::Less, Ordering::Greater) => todo!(), | ||||
|             (Ordering::Less, Ordering::Less) => todo!(), | ||||
|             (Ordering::Equal, _) | (_, Ordering::Equal) => unreachable!("0 must be inline"), | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -66,7 +66,7 @@ macro_rules! basic_op { | ||||
|     }; | ||||
| } | ||||
| 
 | ||||
| fn add_two_slices(slice1: &[u32], slice2: &[u32]) -> Vec<u32> { | ||||
| pub(crate) fn add_two_slices(slice1: &[u32], slice2: &[u32]) -> Vec<u32> { | ||||
|     let s = slice1.len(); | ||||
|     let j = slice2.len(); | ||||
| 
 | ||||
| @ -225,7 +225,7 @@ impl AddAssign<SmallInt> for SmallInt { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn sub_two_slices(slice1: &[u32], slice2: &[u32]) -> Vec<u32> { | ||||
| pub(crate) fn sub_two_slices(slice1: &[u32], slice2: &[u32]) -> Vec<u32> { | ||||
|     let b = slice1.len(); | ||||
|     let s = slice2.len(); | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										357
									
								
								src/tests.rs
									
									
									
									
									
								
							
							
						
						
									
										357
									
								
								src/tests.rs
									
									
									
									
									
								
							| @ -2,6 +2,7 @@ | ||||
| 
 | ||||
| use crate::SmallInt; | ||||
| use crate::SmallUint; | ||||
| use core::fmt::Debug; | ||||
| 
 | ||||
| #[cfg(feature = "num-bigint")] | ||||
| use num_bigint::{BigInt, BigUint, Sign}; | ||||
| @ -32,309 +33,207 @@ conversion_tests!(i64, test_i64); | ||||
| conversion_tests!(u128, test_u128); | ||||
| conversion_tests!(i128, test_i128); | ||||
| 
 | ||||
| fn run_tests_u_inner(test: impl Fn(BigUint)) { | ||||
|     for i in 0u8..=7 { | ||||
|         test(BigUint::from(i)); | ||||
|     } | ||||
|     for shift_scale in 1..=16 { | ||||
|         for shift_offset in -2..=2 { | ||||
|             let shift: i16 = (shift_scale * 32) + shift_offset; | ||||
|             test(BigUint::from(1u8) << shift); | ||||
|             for offset in 1u8..=7 { | ||||
|                 test((BigUint::from(1u8) << shift) + BigUint::from(offset)); | ||||
|                 test((BigUint::from(1u8) << shift) - BigUint::from(offset)); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     test(BigUint::new(vec![3, 9, 8, 3, 1])); | ||||
|     test(BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
| } | ||||
| 
 | ||||
| #[allow(dead_code)] | ||||
| fn run_tests_u_1<T: Eq + Debug>(small: impl Fn(SmallUint) -> T, big: impl Fn(&BigUint) -> T) { | ||||
|     run_tests_u_inner(|i| { | ||||
|         let small_result = small(SmallUint::from(&i)); | ||||
|         let big_result = big(&i); | ||||
|         assert_eq!( | ||||
|             small_result, | ||||
|             big_result, | ||||
|             "{:#x}", i | ||||
|         ); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| fn run_tests_u_2<T: Eq + Debug>( | ||||
|     small: impl Fn(SmallUint, SmallUint) -> T, | ||||
|     big: impl Fn(&BigUint, &BigUint) -> T | ||||
| ) { | ||||
|     run_tests_u_inner(|i| run_tests_u_inner(|k| { | ||||
|         let small_result = small(SmallUint::from(&i), SmallUint::from(&k)); | ||||
|         let big_result = big(&i, &k); | ||||
|         assert_eq!( | ||||
|             small_result, | ||||
|             big_result, | ||||
|             "{:#x} {:#x}", i, k | ||||
|         ); | ||||
|     })); | ||||
| } | ||||
| 
 | ||||
| fn run_tests_i_inner(test: impl Fn(BigInt)) { | ||||
|     run_tests_u_inner(|value| { | ||||
|         test(BigInt::from_biguint(Sign::Plus, value.clone())); | ||||
|         test(BigInt::from_biguint(Sign::Minus, value)); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| fn run_tests_i_1<T: Eq + Debug>(small: impl Fn(SmallInt) -> T, big: impl Fn(&BigInt) -> T) { | ||||
|     run_tests_i_inner(|i| { | ||||
|         let small_result = small(SmallInt::from(&i)); | ||||
|         let big_result = big(&i); | ||||
|         assert_eq!( | ||||
|             small_result, | ||||
|             big_result, | ||||
|             "{:#x}", i | ||||
|         ); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| fn run_tests_i_2<T: Eq + Debug>( | ||||
|     small: impl Fn(SmallInt, SmallInt) -> T, | ||||
|     big: impl Fn(&BigInt, &BigInt) -> T | ||||
| ) { | ||||
|     run_tests_i_inner(|i| run_tests_i_inner(|k| { | ||||
|         let small_result = small(SmallInt::from(&i), SmallInt::from(&k)); | ||||
|         let big_result = big(&i, &k); | ||||
|         assert_eq!( | ||||
|             small_result, | ||||
|             big_result, | ||||
|             "{:#x} {:#x}", i, k | ||||
|         ); | ||||
|     })); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(feature = "num-bigint")] | ||||
| fn test_cmp_u() { | ||||
|     let i = SmallUint::from(30u32); | ||||
|     let k = SmallUint::from(50u32); | ||||
|     assert!(i < k); | ||||
| 
 | ||||
|     let i = SmallUint::from(u128::MAX); | ||||
|     let k = SmallUint::from(&BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
|     assert!(i < k); | ||||
| 
 | ||||
|     let i = SmallUint::from(&BigUint::new(vec![3, 9, 8, 3, 1])); | ||||
|     let k = SmallUint::from(&BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
|     assert!(i < k); | ||||
|     run_tests_u_2( | ||||
|         |i, k| i.partial_cmp(&k), | ||||
|         |i, k| i.partial_cmp(&k), | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(feature = "num-bigint")] | ||||
| fn test_cmp_i() { | ||||
|     let i = SmallInt::from(30u32); | ||||
|     let k = SmallInt::from(50u32); | ||||
|     assert!(i < k); | ||||
| 
 | ||||
|     let i = SmallInt::from(u128::MAX); | ||||
|     let k = SmallInt::from(&BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81])); | ||||
|     assert!(i < k); | ||||
| 
 | ||||
|     let i = SmallInt::from(&BigInt::new(Sign::Plus, vec![3, 9, 8, 3, 1])); | ||||
|     let k = SmallInt::from(&BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81])); | ||||
|     assert!(i < k); | ||||
| 
 | ||||
|     let i = SmallInt::from(30u32); | ||||
|     let k = -SmallInt::from(50u32); | ||||
|     assert!(k < i); | ||||
| 
 | ||||
|     let i = SmallInt::from(u128::MAX); | ||||
|     let k = -SmallInt::from(&BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81])); | ||||
|     assert!(k < i); | ||||
| 
 | ||||
|     let i = SmallInt::from(&BigInt::new(Sign::Plus, vec![3, 9, 8, 3, 1])); | ||||
|     let k = -SmallInt::from(&BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81])); | ||||
|     assert!(k < i); | ||||
|     run_tests_i_2( | ||||
|         |i, k| i.partial_cmp(&k), | ||||
|         |i, k| i.partial_cmp(&k), | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(feature = "num-bigint")] | ||||
| fn test_op_add_u() { | ||||
|     let i = SmallUint::from(u128::MAX); | ||||
|     let k = SmallUint::from(u128::MAX); | ||||
|     let q = i + k; | ||||
|     assert_eq!(BigUint::from(&q), BigUint::from(u128::MAX) + u128::MAX); | ||||
| 
 | ||||
|     let i = SmallUint::from(u128::MAX); | ||||
|     let k = SmallUint::from(&BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
|     let q = i + k; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::new(vec![5, 4, 9, 3, 1, 81]) + u128::MAX | ||||
|     ); | ||||
| 
 | ||||
|     let i = SmallUint::from(&BigUint::new(vec![3, 9, 8, 3, 1])); | ||||
|     let k = SmallUint::from(&BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
|     let q = i + k; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::new(vec![3, 9, 8, 3, 1]) + BigUint::new(vec![5, 4, 9, 3, 1, 81]) | ||||
|     run_tests_u_2( | ||||
|         |i, k| BigUint::from(&(i + k)), | ||||
|         |i, k| i + k, | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(feature = "num-bigint")] | ||||
| fn test_op_add_i() { | ||||
|     let i = SmallInt::from(u128::MAX); | ||||
|     let k = -SmallInt::from(u128::MAX); | ||||
|     let q = i + k; | ||||
|     assert_eq!(BigInt::from(&q), BigInt::from(0)); | ||||
| 
 | ||||
|     let i = SmallInt::from(u128::MAX); | ||||
|     let k = -SmallInt::from(&BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81])); | ||||
|     let q = i + k; | ||||
|     assert_eq!( | ||||
|         BigInt::from(&q), | ||||
|         u128::MAX - BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81]) | ||||
|     ); | ||||
| 
 | ||||
|     let i = -SmallInt::from(&BigInt::new(Sign::Plus, vec![3, 9, 8, 3, 1])); | ||||
|     let k = SmallInt::from(&BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81])); | ||||
|     let q = i + k; | ||||
|     assert_eq!( | ||||
|         BigInt::from(&q), | ||||
|         BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81]) | ||||
|             - BigInt::new(Sign::Plus, vec![3, 9, 8, 3, 1]) | ||||
|     run_tests_i_2( | ||||
|         |i, k| BigInt::from(&(i + k)), | ||||
|         |i, k| i + k, | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(feature = "num-bigint")] | ||||
| fn test_op_mul_u() { | ||||
|     let i = SmallUint::from(u128::MAX); | ||||
|     let k = SmallUint::from(u128::MAX); | ||||
|     let q = i * k; | ||||
|     assert_eq!(BigUint::from(&q), BigUint::from(u128::MAX) * u128::MAX); | ||||
| 
 | ||||
|     let i = SmallUint::from(u32::MAX); | ||||
|     let k = SmallUint::from(&BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
|     let q = i * k; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::new(vec![5, 4, 9, 3, 1, 81]) * u32::MAX | ||||
|     ); | ||||
| 
 | ||||
|     let i = SmallUint::from(&BigUint::new(vec![3, 9, 8, 3, 1])); | ||||
|     let k = SmallUint::from(&BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
|     let q = i * k; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::new(vec![3, 9, 8, 3, 1]) * BigUint::new(vec![5, 4, 9, 3, 1, 81]) | ||||
|     run_tests_u_2( | ||||
|         |i, k| BigUint::from(&(i * k)), | ||||
|         |i, k| i * k, | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(feature = "num-bigint")] | ||||
| fn test_op_mul_i() { | ||||
|     let i = -SmallInt::from(u128::MAX); | ||||
|     let k = SmallInt::from(u128::MAX); | ||||
|     let q = i * k; | ||||
|     assert_eq!(BigInt::from(&q), -BigInt::from(u128::MAX) * u128::MAX); | ||||
| 
 | ||||
|     let i = -SmallInt::from(u32::MAX); | ||||
|     let k = -SmallInt::from(&BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81])); | ||||
|     let q = i * k; | ||||
|     assert_eq!( | ||||
|         BigInt::from(&q), | ||||
|         BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81]) * u32::MAX | ||||
|     ); | ||||
| 
 | ||||
|     let i = -SmallInt::from(&BigInt::new(Sign::Plus, vec![3, 9, 8, 3, 1])); | ||||
|     let k = SmallInt::from(&BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81])); | ||||
|     let q = i * k; | ||||
|     assert_eq!( | ||||
|         BigInt::from(&q), | ||||
|         BigInt::new(Sign::Plus, vec![3, 9, 8, 3, 1]) | ||||
|             * -BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81]) | ||||
|     run_tests_i_2( | ||||
|         |i, k| BigInt::from(&(i * k)), | ||||
|         |i, k| i * k, | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(feature = "num-bigint")] | ||||
| fn test_op_sub_u() { | ||||
|     let i = SmallUint::from(u128::MAX); | ||||
|     let k = SmallUint::from(u128::MAX); | ||||
|     let q = i - k; | ||||
|     assert_eq!(BigUint::from(&q), BigUint::from(u128::MAX) - u128::MAX); | ||||
| 
 | ||||
|     let k = SmallUint::from(&BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
|     let i = SmallUint::from(u128::MAX); | ||||
|     let q = k - i; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::new(vec![5, 4, 9, 3, 1, 81]) - u128::MAX | ||||
|     ); | ||||
| 
 | ||||
|     let k = SmallUint::from(&BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
|     let i = SmallUint::from(&BigUint::new(vec![3, 9, 8, 3, 1])); | ||||
|     let q = k - i; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::new(vec![5, 4, 9, 3, 1, 81]) - BigUint::new(vec![3, 9, 8, 3, 1]) | ||||
|     run_tests_u_2( | ||||
|         |i, k| (i >= k).then(|| BigUint::from(&(i - k))), | ||||
|         |i, k| (i >= k).then(|| i - k), | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(feature = "num-bigint")] | ||||
| fn test_op_sub_i() { | ||||
|     let i = -SmallInt::from(u128::MAX); | ||||
|     let k = SmallInt::from(u128::MAX); | ||||
|     let q = i - k; | ||||
|     assert_eq!(BigInt::from(&q), -BigInt::from(u128::MAX) - u128::MAX); | ||||
| 
 | ||||
|     let k = SmallInt::from(&BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81])); | ||||
|     let i = -SmallInt::from(u128::MAX); | ||||
|     let q = k - i; | ||||
|     assert_eq!( | ||||
|         BigInt::from(&q), | ||||
|         BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81]) + u128::MAX | ||||
|     ); | ||||
| 
 | ||||
|     let k = -SmallInt::from(&BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81])); | ||||
|     let i = SmallInt::from(&BigInt::new(Sign::Plus, vec![3, 9, 8, 3, 1])); | ||||
|     let q = k - i; | ||||
|     assert_eq!( | ||||
|         BigInt::from(&q), | ||||
|         -(BigInt::new(Sign::Plus, vec![5, 4, 9, 3, 1, 81]) | ||||
|             + BigInt::new(Sign::Plus, vec![3, 9, 8, 3, 1])) | ||||
|     run_tests_i_2( | ||||
|         |i, k| BigInt::from(&(i - k)), | ||||
|         |i, k| i - k, | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(feature = "num-bigint")] | ||||
| fn test_op_and_u() { | ||||
|     let i = SmallUint::from(u128::MAX); | ||||
|     let k = SmallUint::from(u128::MAX); | ||||
|     let q = i & k; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::from(u128::MAX) & BigUint::from(u128::MAX) | ||||
|     run_tests_u_2( | ||||
|         |i, k| BigUint::from(&(i & k)), | ||||
|         |i, k| i & k, | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
|     let k = SmallUint::from(&BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
|     let i = SmallUint::from(u128::MAX); | ||||
|     let q = k & i; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::new(vec![5, 4, 9, 3]) & BigUint::from(u128::MAX) | ||||
|     ); | ||||
| 
 | ||||
|     let k = SmallUint::from(&BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
|     let i = SmallUint::from(&BigUint::new(vec![3, 9, 8, 3, 1])); | ||||
|     let q = k & i; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::new(vec![5, 4, 9, 3, 1, 81]) & BigUint::new(vec![3, 9, 8, 3, 1]) | ||||
| #[test] | ||||
| #[cfg(feature = "num-bigint")] | ||||
| fn test_op_and_i() { | ||||
|     run_tests_i_2( | ||||
|         |i, k| BigInt::from(&(i & k)), | ||||
|         |i, k| i & k, | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(feature = "num-bigint")] | ||||
| fn test_op_or_u() { | ||||
|     let i = SmallUint::from(u128::MAX); | ||||
|     let k = SmallUint::from(u128::MAX); | ||||
|     let q = i | k; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::from(u128::MAX) | BigUint::from(u128::MAX) | ||||
|     ); | ||||
| 
 | ||||
|     let k = SmallUint::from(&BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
|     let i = SmallUint::from(u128::MAX); | ||||
|     let q = k | i; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::new(vec![5, 4, 9, 3, 1, 81]) | BigUint::from(u128::MAX) | ||||
|     ); | ||||
| 
 | ||||
|     let k = SmallUint::from(&BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
|     let i = SmallUint::from(&BigUint::new(vec![3, 9, 8, 3, 1])); | ||||
|     let q = k | i; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::new(vec![5, 4, 9, 3, 1, 81]) | BigUint::new(vec![3, 9, 8, 3, 1]) | ||||
|     run_tests_u_2( | ||||
|         |i, k| BigUint::from(&(i | k)), | ||||
|         |i, k| i | k, | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(feature = "num-bigint")] | ||||
| fn test_op_xor_u() { | ||||
|     let i = SmallUint::from(u128::MAX); | ||||
|     let k = SmallUint::from(u128::MAX); | ||||
|     let q = i ^ k; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::from(u128::MAX) ^ BigUint::from(u128::MAX) | ||||
|     ); | ||||
| 
 | ||||
|     let k = SmallUint::from(&BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
|     let i = SmallUint::from(u128::MAX); | ||||
|     let q = k ^ i; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::new(vec![5, 4, 9, 3, 1, 81]) ^ BigUint::from(u128::MAX) | ||||
|     ); | ||||
| 
 | ||||
|     let k = SmallUint::from(&BigUint::new(vec![5, 4, 9, 3, 1, 81])); | ||||
|     let i = SmallUint::from(&BigUint::new(vec![3, 9, 8, 3, 1])); | ||||
|     let q = k ^ i; | ||||
|     assert_eq!( | ||||
|         BigUint::from(&q), | ||||
|         BigUint::new(vec![5, 4, 9, 3, 1, 81]) ^ BigUint::new(vec![3, 9, 8, 3, 1]) | ||||
|     run_tests_u_2( | ||||
|         |i, k| BigUint::from(&(i ^ k)), | ||||
|         |i, k| i ^ k, | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(feature = "num-bigint")] | ||||
| fn test_op_neg() { | ||||
|     let i = SmallInt::from(u128::MAX); | ||||
|     let q = -i; | ||||
|     assert_eq!(BigInt::from(&q), -BigInt::from(u128::MAX)); | ||||
| 
 | ||||
|     let i = SmallInt::from(i128::MAX); | ||||
|     let q = -i; | ||||
|     assert_eq!(BigInt::from(&q), -BigInt::from(i128::MAX)); | ||||
| 
 | ||||
|     let i = SmallInt::from(i128::MIN); | ||||
|     let q = -i; | ||||
|     assert_eq!(BigInt::from(&q), -BigInt::from(i128::MIN)); | ||||
|     run_tests_i_1(|i| BigInt::from(&-i), |i| -i.clone()); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
| #[cfg(feature = "num-bigint")] | ||||
| fn test_conversion_sign_drop() { | ||||
|     let si = SmallInt::from(i128::MIN + 1); | ||||
|     let i = SmallUint::from_smallint_unsigned(si); | ||||
|     assert_eq!(BigUint::from(&i), BigUint::from(-(i128::MIN + 1) as u128)) | ||||
|     run_tests_i_1( | ||||
|         |i| BigUint::from(&SmallUint::from_smallint_unsigned(i)), | ||||
|         |i| i.magnitude().clone() | ||||
|     ); | ||||
| } | ||||
| 
 | ||||
| #[test] | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user