pub fn set_bit(num: u64, bit_index: u64, value: bool) -> u64 {
let v = 1 << bit_index;
if value {
num | v
} else {
num & !v
}
}
pub fn get_bit(num: u64, bit_index: u64) -> bool {
((num >> bit_index) & 1) != 0
}
pub fn entwine_bits(n: u64, mut selector: u64, mut off_bits: u64, mut on_bits: u64) -> u64 {
let mut result = 0;
for i in 0..n {
if selector & 1 == 0 {
let bit = off_bits & 1;
off_bits >>= 1;
result |= bit << i;
} else {
let bit = on_bits & 1;
on_bits >>= 1;
result |= bit << i;
}
selector >>= 1;
}
result
}
pub fn get_flat_index(nindices: u64, i: u64, j: u64) -> u64 {
let mat_side = 1 << nindices;
(i * mat_side) + j
}
pub fn flip_bits(n: usize, num: u64) -> u64 {
let leading_zeros = 64 - n;
num.reverse_bits() >> leading_zeros
}
pub fn extract_bits(num: u64, indices: &[u64]) -> u64 {
indices.iter().enumerate().fold(0, |acc, (i, index)| {
let bit = (num >> index) & 1;
acc | (bit << i)
})
}