#[cfg(not(any(target_pointer_width = "64",)))]
compile_error! {
"This crate requires the platform pointer to have a width of 64"
}
pub mod four_russians_msb;
pub mod sardine_can;
pub use four_russians_msb::get_msb_idx_of;
pub use four_russians_msb::lcp_len_of;
pub use four_russians_msb::FourRussiansMSB;
pub use sardine_can::SardineCan;
const USIZE_BITS: usize = 64;
pub fn top_k_bits_of(x: usize, k: usize) -> usize {
assert!(k != 0);
let mut mask: usize = 1;
mask <<= USIZE_BITS - k;
mask = !mask;
mask += 1;
x & mask
}
#[cfg(test)]
mod test_bit_parallelism {
use pretty_assertions::assert_eq;
use rand::Rng;
use super::four_russians_msb;
use super::sardine_can;
#[test]
fn sardine_add() {
let mut rng = rand::thread_rng();
let mut can = sardine_can::SardineCan::default();
for _ in 0..8 {
let small_int = rng.gen_range(0..=1 << 7);
can.add(small_int);
println!("{:b}, can is {}", small_int, can)
}
}
#[test]
fn sardine_tile() {
let tiled = sardine_can::SardineCan::parallel_tile_64(0b1100111);
println!("{:b}", tiled)
}
#[test]
fn test_stacker() {
let a = 0b10000000_10000000_10000000_10000000_10000000_10000000_100000001u64;
let b = 0b10000000_00000000_10000000_10000000_00000000_10000000_00000000_10000000u64;
let mut c = a as u128 * b as u128;
println!("{:b}", c);
c >>= 63;
println!("{:b}", c);
println!("{}", c & 0b111);
}
#[test]
fn sardine_rank() {
let mut rng = rand::thread_rng();
let mut can = sardine_can::SardineCan::default();
for _ in 0..8 {
let small_int = rng.gen_range(0..=1 << 7);
can.add(small_int);
}
println!("{}", can.parallel_rank(0b1100111));
}
#[test]
fn pack() {
let tt = 0b00010000_10000000_10000000_10000000_10000000_00000000_00000000_00000000u64;
let m = 0b10000001_00000010_00000100_00001000_00010000_00100000_010000001u64;
let mut c = tt as u128 * m as u128;
println!("{:b}", c);
c >>= 49;
println!("{:b}", c);
if tt >> 56 == 0 {
c &= 0b0111_1111;
} else {
c |= 0b1000_0000;
c &= 0b1111_1111;
}
println!("{:b}", c);
}
#[test]
fn get_msb() {
let msb = four_russians_msb::get_msb_idx_of(873);
assert_eq!(9, msb);
let base: usize = 2;
let msb = four_russians_msb::get_msb_idx_of(base.pow(32) as u64);
assert_eq!(32, msb);
let msb = four_russians_msb::get_msb_idx_of(base.pow(55) as u64);
assert_eq!(55, msb);
let msb = four_russians_msb::get_msb_idx_of((base.pow(56) + 13) as u64);
assert_eq!(56, msb);
let msb = four_russians_msb::get_msb_idx_of((base.pow(61) + 31) as u64);
assert_eq!(61, msb);
let msb = four_russians_msb::get_msb_idx_of((2u128.pow(64) - 1) as u64);
assert_eq!(63, msb);
let msb = four_russians_msb::get_msb_idx_of(base.pow(48) as u64);
assert_eq!(48, msb);
let msb = four_russians_msb::get_msb_idx_of(base.pow(63) as u64);
assert_eq!(63, msb);
let msb = four_russians_msb::get_msb_idx_of(255);
assert_eq!(7, msb);
let msb = four_russians_msb::get_msb_idx_of(1);
assert_eq!(0, msb);
let msb = four_russians_msb::get_msb_idx_of(16);
assert_eq!(4, msb);
let msb = four_russians_msb::get_msb_idx_of(256);
assert_eq!(8, msb);
let msb = four_russians_msb::get_msb_idx_of(25);
assert_eq!(4, msb);
let msb = four_russians_msb::get_msb_idx_of(91);
assert_eq!(6, msb);
let msb = four_russians_msb::get_msb_idx_of(base.pow(16) as u64);
assert_eq!(16, msb);
let msb = four_russians_msb::get_msb_idx_of(1 << 18);
assert_eq!(18, msb);
}
}