mirror of
https://gitlab.com/artofrev/smallint.git
synced 2024-12-04 17:11:38 -05:00
stuff
This commit is contained in:
parent
234fce4b92
commit
c392ba8633
134
src/logic.rs
134
src/logic.rs
|
@ -130,7 +130,7 @@ macro_rules! inline_heap_to_heap {
|
||||||
|
|
||||||
let mut retslice = ManuallyDrop::new(retvec.into_boxed_slice());
|
let mut retslice = ManuallyDrop::new(retvec.into_boxed_slice());
|
||||||
|
|
||||||
$typ($typ_inner::Heap((retslice.as_mut_ptr(), retslice.len())))
|
$typ($typ_inner::Heap((retslice.as_mut_ptr(), retslice.len().try_into().unwrap())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,31 +160,31 @@ macro_rules! heap_heap_create_res_longest {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
macro_rules! heap_heap_return_heap_inner {
|
macro_rules! return_heap_inner {
|
||||||
($typ:ident, $typ_inner:ident; $res:ident) => {
|
($typ:ident, $typ_inner:ident; $res:ident) => {
|
||||||
let mut slice = ManuallyDrop::new($res);
|
let mut slice = ManuallyDrop::new($res);
|
||||||
$typ($typ_inner::Heap((slice.as_mut_ptr(), slice.len().try_into().unwrap())))
|
$typ($typ_inner::Heap((slice.as_mut_ptr(), slice.len().try_into().unwrap())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! heap_heap_return_heap_inner_neg {
|
macro_rules! return_heap_inner_neg {
|
||||||
($typ:ident, $typ_inner:ident; $res:ident) => {
|
($typ:ident, $typ_inner:ident; $res:ident) => {
|
||||||
let mut slice = ManuallyDrop::new($res);
|
let mut slice = ManuallyDrop::new($res);
|
||||||
$typ($typ_inner::Heap((slice.as_mut_ptr(), -isize::try_from(slice.len()).unwrap())))
|
$typ($typ_inner::Heap((slice.as_mut_ptr(), -isize::try_from(slice.len()).unwrap())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! heap_heap_return_heap {
|
macro_rules! return_heap {
|
||||||
($typ:ident, $typ_inner:ident; $res:ident) => {
|
($typ:ident, $typ_inner:ident; $res:ident) => {
|
||||||
let res = $res.into_boxed_slice();
|
let res = $res.into_boxed_slice();
|
||||||
heap_heap_return_heap_inner! { $typ, $typ_inner; res }
|
return_heap_inner! { $typ, $typ_inner; res }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! heap_heap_return_heap_neg {
|
macro_rules! return_heap_neg {
|
||||||
($typ:ident, $typ_inner:ident; $res:ident) => {
|
($typ:ident, $typ_inner:ident; $res:ident) => {
|
||||||
let res = $res.into_boxed_slice();
|
let res = $res.into_boxed_slice();
|
||||||
heap_heap_return_heap_inner_neg! { $typ, $typ_inner; res }
|
return_heap_inner_neg! { $typ, $typ_inner; res }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ logic_op! {
|
||||||
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_heap! { bitor_assign, SmallUint, SmallUintType; i, slice } },
|
{ inline_heap_to_heap! { bitor_assign, SmallUint, SmallUintType; i, slice } },
|
||||||
{ heap_heap_create_res_longest! { bitor; slice1, slice2, min }},
|
{ heap_heap_create_res_longest! { bitor; slice1, slice2, min }},
|
||||||
{ heap_heap_return_heap! { SmallUint, SmallUintType; res } }
|
{ return_heap! { SmallUint, SmallUintType; res } }
|
||||||
}
|
}
|
||||||
|
|
||||||
logic_op! {
|
logic_op! {
|
||||||
|
@ -256,6 +256,28 @@ fn bitand_two_slices_mixed_sign(positive: &[u32], negative: &[u32]) -> Vec<u32>
|
||||||
sub2
|
sub2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn bitand_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 bitor_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 = bitand_two_slices(positive, &sub1);
|
||||||
|
let add = add_two_slices(&or, &[1]);
|
||||||
|
let sub2 = sub_two_slices(&add, negative);
|
||||||
|
sub2
|
||||||
|
}
|
||||||
|
|
||||||
logic_op! {
|
logic_op! {
|
||||||
BitAnd, BitAndAssign, SmallInt, SmallIntType, bitand, bitand_assign;
|
BitAnd, BitAndAssign, SmallInt, SmallIntType, bitand, bitand_assign;
|
||||||
i, j, p, q, s, t;
|
i, j, p, q, s, t;
|
||||||
|
@ -278,7 +300,7 @@ logic_op! {
|
||||||
res[idx] &= inline as u32;
|
res[idx] &= inline as u32;
|
||||||
inline >>= 32;
|
inline >>= 32;
|
||||||
}
|
}
|
||||||
heap_heap_return_heap_inner! { SmallInt, SmallIntType; res }
|
return_heap_inner! { SmallInt, SmallIntType; res }
|
||||||
},
|
},
|
||||||
(Ordering::Less, Ordering::Less) => {
|
(Ordering::Less, Ordering::Less) => {
|
||||||
let mut res = <Box<[u32]>>::from(slice);
|
let mut res = <Box<[u32]>>::from(slice);
|
||||||
|
@ -292,9 +314,9 @@ logic_op! {
|
||||||
|
|
||||||
if lo == 0 && j != 0 {
|
if lo == 0 && j != 0 {
|
||||||
let res2 = add_two_slices(&res, &[0, 0, 0, 0, 1]);
|
let res2 = add_two_slices(&res, &[0, 0, 0, 0, 1]);
|
||||||
heap_heap_return_heap_neg! { SmallInt, SmallIntType; res2 }
|
return_heap_neg! { SmallInt, SmallIntType; res2 }
|
||||||
} else {
|
} else {
|
||||||
heap_heap_return_heap_inner_neg! { SmallInt, SmallIntType; res }
|
return_heap_inner_neg! { SmallInt, SmallIntType; res }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(_, Ordering::Equal) => unreachable!("0 must be inline"),
|
(_, Ordering::Equal) => unreachable!("0 must be inline"),
|
||||||
|
@ -309,16 +331,16 @@ logic_op! {
|
||||||
|
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let mut res = { heap_heap_create_res_shortest! { bitand; slice1, slice2, min } };
|
let mut res = { heap_heap_create_res_shortest! { bitand; slice1, slice2, min } };
|
||||||
|
// TODO: shrink if needed, sometimes to Inline
|
||||||
heap_heap_return_heap! { SmallInt, SmallIntType; res }
|
return_heap! { SmallInt, SmallIntType; res }
|
||||||
},
|
},
|
||||||
(Ordering::Greater, Ordering::Less) => {
|
(Ordering::Greater, Ordering::Less) => {
|
||||||
let res = bitand_two_slices_mixed_sign(slice1, slice2);
|
let res = bitand_two_slices_mixed_sign(slice1, slice2);
|
||||||
heap_heap_return_heap! { SmallInt, SmallIntType; res }
|
return_heap! { SmallInt, SmallIntType; res }
|
||||||
},
|
},
|
||||||
(Ordering::Less, Ordering::Greater) => {
|
(Ordering::Less, Ordering::Greater) => {
|
||||||
let res = bitand_two_slices_mixed_sign(slice2, slice1);
|
let res = bitand_two_slices_mixed_sign(slice2, slice1);
|
||||||
heap_heap_return_heap! { SmallInt, SmallIntType; res }
|
return_heap! { SmallInt, SmallIntType; res }
|
||||||
},
|
},
|
||||||
(Ordering::Less, Ordering::Less) => {
|
(Ordering::Less, Ordering::Less) => {
|
||||||
// (-a) & (-b) = -(((a-1) | (b-1)) + 1)
|
// (-a) & (-b) = -(((a-1) | (b-1)) + 1)
|
||||||
|
@ -327,9 +349,89 @@ logic_op! {
|
||||||
let sub2 = sub_two_slices(slice2, &[1]);
|
let sub2 = sub_two_slices(slice2, &[1]);
|
||||||
let tmp = bitor_two_slices(&sub1, &sub2);
|
let tmp = bitor_two_slices(&sub1, &sub2);
|
||||||
let res = add_two_slices(&tmp, &[1]);
|
let res = add_two_slices(&tmp, &[1]);
|
||||||
heap_heap_return_heap_neg! { SmallInt, SmallIntType; res }
|
return_heap_neg! { SmallInt, SmallIntType; res }
|
||||||
},
|
},
|
||||||
(Ordering::Equal, _) | (_, Ordering::Equal) => unreachable!("0 must be inline"),
|
(Ordering::Equal, _) | (_, Ordering::Equal) => unreachable!("0 must be inline"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// logic_op! {
|
||||||
|
// BitOr, BitOrAssign, SmallInt, SmallIntType, bitor, bitor_assign;
|
||||||
|
// i, j, p, q, s, t;
|
||||||
|
// {
|
||||||
|
// let slice = unsafe { core::slice::from_raw_parts(p, s.unsigned_abs()) };
|
||||||
|
// match (i.cmp(&0), s.cmp(&0)) {
|
||||||
|
// (Ordering::Equal, _) => {
|
||||||
|
// let mut slice = ManuallyDrop::new(<Box<[_]>>::from(slice));
|
||||||
|
// SmallInt(SmallIntType::Heap((slice.as_mut_ptr(), s)))
|
||||||
|
// },
|
||||||
|
// (Ordering::Greater, Ordering::Greater) => {
|
||||||
|
// inline_heap_to_heap! { bitor_assign, SmallInt, SmallIntType; i, slice }
|
||||||
|
// },
|
||||||
|
// (Ordering::Greater, Ordering::Less) => {
|
||||||
|
// let mut res = <Box<[u32]>>::from(slice);
|
||||||
|
// let mut inline = i as u128;
|
||||||
|
// for idx in 0..4 {
|
||||||
|
// res[idx] = ((res[idx] as i32).wrapping_neg() | (inline as i32).wrapping_neg()).wrapping_neg() as u32;
|
||||||
|
// inline >>= 32;
|
||||||
|
// }
|
||||||
|
// return_heap_inner_neg! { SmallInt, SmallIntType; res }
|
||||||
|
// },
|
||||||
|
// (Ordering::Less, Ordering::Greater) => {
|
||||||
|
// let j = { heap_to_inline! { i128; slice } };
|
||||||
|
// SmallInt(SmallIntType::Inline(i | -j))
|
||||||
|
// },
|
||||||
|
// (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]);
|
||||||
|
// return_heap_neg! { SmallInt, SmallIntType; res2 }
|
||||||
|
// } else {
|
||||||
|
// 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.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! { bitor; slice1, slice2, min } };
|
||||||
|
//
|
||||||
|
// return_heap! { SmallInt, SmallIntType; res }
|
||||||
|
// },
|
||||||
|
// (Ordering::Greater, Ordering::Less) => {
|
||||||
|
// let res = bitor_two_slices_mixed_sign(slice1, slice2);
|
||||||
|
// return_heap! { SmallInt, SmallIntType; res }
|
||||||
|
// },
|
||||||
|
// (Ordering::Less, Ordering::Greater) => {
|
||||||
|
// let res = bitor_two_slices_mixed_sign(slice2, slice1);
|
||||||
|
// 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 = bitand_two_slices(&sub1, &sub2);
|
||||||
|
// let res = add_two_slices(&tmp, &[1]);
|
||||||
|
// return_heap_neg! { SmallInt, SmallIntType; res }
|
||||||
|
// },
|
||||||
|
// (Ordering::Equal, _) | (_, Ordering::Equal) => unreachable!("0 must be inline"),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
|
@ -232,6 +232,15 @@ fn test_op_or_u() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
// #[cfg(feature = "num-bigint")]
|
||||||
|
// fn test_op_or_i() {
|
||||||
|
// run_tests_i_2(
|
||||||
|
// |i, k| BigInt::from(&(i | k)),
|
||||||
|
// |i, k| i | k,
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(feature = "num-bigint")]
|
#[cfg(feature = "num-bigint")]
|
||||||
fn test_op_xor_u() {
|
fn test_op_xor_u() {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user