mirror of
https://gitlab.com/artofrev/smallint.git
synced 2024-12-04 17:11:38 -05: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]
|
[dev-dependencies]
|
||||||
num-bigint = { version = "0.4.3" }
|
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::{SmallIntType, SmallUintType};
|
||||||
use crate::{SmallInt, SmallUint};
|
use crate::{SmallInt, SmallUint};
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
|
@ -97,13 +98,20 @@ macro_rules! logic_op {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
macro_rules! inline_heap_to_inline {
|
macro_rules! heap_to_inline {
|
||||||
($fun:ident, $typ:ident, $typ_inner:ident, $typ_inline:ident; $i:ident, $slice:ident) => {
|
($typ_inline:ident; $slice:ident) => {
|
||||||
let mut j = 0;
|
let mut j = 0;
|
||||||
for i in 0..4 {
|
for i in 0..4 {
|
||||||
j <<= 32;
|
j <<= 32;
|
||||||
j |= $slice[3 - i] as $typ_inline;
|
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)))
|
$typ($typ_inner::Inline($i.$fun(j)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +136,7 @@ macro_rules! inline_heap_to_heap {
|
||||||
|
|
||||||
|
|
||||||
macro_rules! heap_heap_create_res_shortest {
|
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);
|
let mut res = Vec::with_capacity($min);
|
||||||
for l in 0..$min {
|
for l in 0..$min {
|
||||||
res.push($slice1[l].$fun($slice2[l]));
|
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 {
|
macro_rules! heap_heap_return_heap {
|
||||||
($typ:ident, $typ_inner:ident; $res:ident) => {
|
($typ:ident, $typ_inner:ident; $res:ident) => {
|
||||||
let mut slice = ManuallyDrop::new($res.into_boxed_slice());
|
let res = $res.into_boxed_slice();
|
||||||
$typ($typ_inner::Heap((slice.as_mut_ptr(), slice.len().try_into().unwrap())))
|
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;
|
BitAnd, BitAndAssign, SmallUint, SmallUintType, bitand, bitand_assign;
|
||||||
i, j, p, q, s, t, slice, slice1, slice2, min, res;
|
i, j, p, q, s, t, slice, slice1, slice2, min, res;
|
||||||
{ inline_heap_to_inline! { bitand, SmallUint, SmallUintType, u128; i, slice } },
|
{ 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 } }
|
{ 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! {
|
logic_op! {
|
||||||
BitXor, BitXorAssign, SmallInt, SmallIntType, bitxor, bitxor_assign;
|
BitAnd, BitAndAssign, SmallInt, SmallIntType, bitand, bitand_assign;
|
||||||
i, j, p, q, s, t;
|
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 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)) {
|
match (s.cmp(&0), t.cmp(&0)) {
|
||||||
(Ordering::Greater, Ordering::Greater) => {
|
(Ordering::Greater, Ordering::Greater) => {
|
||||||
let min = std::cmp::min(slice1.len(), slice2.len());
|
let min = std::cmp::min(slice1.len(), slice2.len());
|
||||||
|
|
||||||
#[allow(unused_mut)]
|
#[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"),
|
(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 s = slice1.len();
|
||||||
let j = slice2.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 b = slice1.len();
|
||||||
let s = slice2.len();
|
let s = slice2.len();
|
||||||
|
|
||||||
|
|
357
src/tests.rs
357
src/tests.rs
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use crate::SmallInt;
|
use crate::SmallInt;
|
||||||
use crate::SmallUint;
|
use crate::SmallUint;
|
||||||
|
use core::fmt::Debug;
|
||||||
|
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
use num_bigint::{BigInt, BigUint, Sign};
|
use num_bigint::{BigInt, BigUint, Sign};
|
||||||
|
@ -32,309 +33,207 @@ conversion_tests!(i64, test_i64);
|
||||||
conversion_tests!(u128, test_u128);
|
conversion_tests!(u128, test_u128);
|
||||||
conversion_tests!(i128, test_i128);
|
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]
|
#[test]
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
fn test_cmp_u() {
|
fn test_cmp_u() {
|
||||||
let i = SmallUint::from(30u32);
|
run_tests_u_2(
|
||||||
let k = SmallUint::from(50u32);
|
|i, k| i.partial_cmp(&k),
|
||||||
assert!(i < k);
|
|i, k| i.partial_cmp(&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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
fn test_cmp_i() {
|
fn test_cmp_i() {
|
||||||
let i = SmallInt::from(30u32);
|
run_tests_i_2(
|
||||||
let k = SmallInt::from(50u32);
|
|i, k| i.partial_cmp(&k),
|
||||||
assert!(i < k);
|
|i, k| i.partial_cmp(&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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
fn test_op_add_u() {
|
fn test_op_add_u() {
|
||||||
let i = SmallUint::from(u128::MAX);
|
run_tests_u_2(
|
||||||
let k = SmallUint::from(u128::MAX);
|
|i, k| BigUint::from(&(i + k)),
|
||||||
let q = i + k;
|
|i, k| 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])
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
fn test_op_add_i() {
|
fn test_op_add_i() {
|
||||||
let i = SmallInt::from(u128::MAX);
|
run_tests_i_2(
|
||||||
let k = -SmallInt::from(u128::MAX);
|
|i, k| BigInt::from(&(i + k)),
|
||||||
let q = i + k;
|
|i, k| 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])
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
fn test_op_mul_u() {
|
fn test_op_mul_u() {
|
||||||
let i = SmallUint::from(u128::MAX);
|
run_tests_u_2(
|
||||||
let k = SmallUint::from(u128::MAX);
|
|i, k| BigUint::from(&(i * k)),
|
||||||
let q = i * k;
|
|i, k| 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])
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
fn test_op_mul_i() {
|
fn test_op_mul_i() {
|
||||||
let i = -SmallInt::from(u128::MAX);
|
run_tests_i_2(
|
||||||
let k = SmallInt::from(u128::MAX);
|
|i, k| BigInt::from(&(i * k)),
|
||||||
let q = i * k;
|
|i, k| 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])
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
fn test_op_sub_u() {
|
fn test_op_sub_u() {
|
||||||
let i = SmallUint::from(u128::MAX);
|
run_tests_u_2(
|
||||||
let k = SmallUint::from(u128::MAX);
|
|i, k| (i >= k).then(|| BigUint::from(&(i - k))),
|
||||||
let q = i - k;
|
|i, k| (i >= k).then(|| 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])
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
fn test_op_sub_i() {
|
fn test_op_sub_i() {
|
||||||
let i = -SmallInt::from(u128::MAX);
|
run_tests_i_2(
|
||||||
let k = SmallInt::from(u128::MAX);
|
|i, k| BigInt::from(&(i - k)),
|
||||||
let q = i - k;
|
|i, k| 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]))
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
fn test_op_and_u() {
|
fn test_op_and_u() {
|
||||||
let i = SmallUint::from(u128::MAX);
|
run_tests_u_2(
|
||||||
let k = SmallUint::from(u128::MAX);
|
|i, k| BigUint::from(&(i & k)),
|
||||||
let q = i & k;
|
|i, k| 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]));
|
#[test]
|
||||||
let i = SmallUint::from(u128::MAX);
|
#[cfg(feature = "num-bigint")]
|
||||||
let q = k & i;
|
fn test_op_and_i() {
|
||||||
assert_eq!(
|
run_tests_i_2(
|
||||||
BigUint::from(&q),
|
|i, k| BigInt::from(&(i & k)),
|
||||||
BigUint::new(vec![5, 4, 9, 3]) & BigUint::from(u128::MAX)
|
|i, k| i & k,
|
||||||
);
|
|
||||||
|
|
||||||
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]
|
#[test]
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
fn test_op_or_u() {
|
fn test_op_or_u() {
|
||||||
let i = SmallUint::from(u128::MAX);
|
run_tests_u_2(
|
||||||
let k = SmallUint::from(u128::MAX);
|
|i, k| BigUint::from(&(i | k)),
|
||||||
let q = i | k;
|
|i, k| 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])
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
fn test_op_xor_u() {
|
fn test_op_xor_u() {
|
||||||
let i = SmallUint::from(u128::MAX);
|
run_tests_u_2(
|
||||||
let k = SmallUint::from(u128::MAX);
|
|i, k| BigUint::from(&(i ^ k)),
|
||||||
let q = i ^ k;
|
|i, k| 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])
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
fn test_op_neg() {
|
fn test_op_neg() {
|
||||||
let i = SmallInt::from(u128::MAX);
|
run_tests_i_1(|i| BigInt::from(&-i), |i| -i.clone());
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
fn test_conversion_sign_drop() {
|
fn test_conversion_sign_drop() {
|
||||||
let si = SmallInt::from(i128::MIN + 1);
|
run_tests_i_1(
|
||||||
let i = SmallUint::from_smallint_unsigned(si);
|
|i| BigUint::from(&SmallUint::from_smallint_unsigned(i)),
|
||||||
assert_eq!(BigUint::from(&i), BigUint::from(-(i128::MIN + 1) as u128))
|
|i| i.magnitude().clone()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user