Skip to content

Commit

Permalink
add is_pow_2
Browse files Browse the repository at this point in the history
  • Loading branch information
ekiwi committed Nov 20, 2024
1 parent 01ec209 commit 33b158b
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "baa"
version = "0.14.3"
version = "0.14.4"
edition = "2021"
authors = ["Kevin Laeufer <[email protected]>"]
description = "BitVector and Array Arithmetic"
Expand Down
38 changes: 38 additions & 0 deletions src/bv/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,28 @@ pub trait BitVecOps {
crate::bv::arithmetic::is_neg(self.words(), self.width())
}

fn is_pow_2(&self) -> Option<WidthInt> {
// find most significant bit set
let mut bit_pos = None;
for (word_ii, &word) in self.words().iter().enumerate() {
if bit_pos.is_none() {
if word != 0 {
// is there only one bit set?
if word.leading_zeros() + word.trailing_zeros() == Word::BITS - 1 {
bit_pos = Some(word.trailing_zeros() + word_ii as WidthInt * Word::BITS);
} else {
// more than one bit set
return None;
}
}
} else if word != 0 {
// more than one bit set
return None;
}
}
bit_pos
}

declare_arith_bin_fn!(add);
declare_arith_bin_fn!(sub);
declare_arith_bin_fn!(shift_left);
Expand Down Expand Up @@ -621,4 +643,20 @@ mod tests {
a.set_bit(20);
assert!(!a.is_one());
}

#[test]
fn test_is_pow_2() {
let mut a = BitVecValue::zero(1456);
assert_eq!(a.is_pow_2(), None);
a.set_bit(0);
assert_eq!(a.is_pow_2(), Some(0));
a.set_bit(20);
assert_eq!(a.is_pow_2(), None);

for bit in 0..a.width() {
a.clear();
a.set_bit(bit);
assert_eq!(a.is_pow_2(), Some(bit));
}
}
}

0 comments on commit 33b158b

Please sign in to comment.