Rust Counting Bits
Bit counting methods are integer methods that count set bits and find where a value starts. count_ones counts the 1 bits in a number.
Count the set bits: count_ones
This is the count programmers call the population count — how many facts are switched on:
let n = 0b1011_0100u8;
println!("set bits = {}", n.count_ones());Count the clear bits: count_zeros
The same number asked the other way. 4 set and 4 clear add up to the 8 bits of a u8:
let n = 0b1011_0100u8;
println!("clear bits = {}", n.count_zeros());Empty space at the front: leading_zeros
leading_zeros counts the zeros before the first 1:
let n = 0b0000_1010u8;
println!("leading zeros = {}", n.leading_zeros());Empty space at the back: trailing_zeros
trailing_zeros counts the zeros after the last 1 — so it names the position of the lowest set bit:
let n = 0b1011_0100u8;
println!("trailing zeros = {}", n.trailing_zeros());How big in binary: ilog2
ilog2 says how many times a number can be halved before it reaches 1. That count is the number of binary digits minus one. Zero has no answer, so the checked version returns None:
println!("{}", 8u32.ilog2());
println!("{}", 9u32.ilog2());
println!("{:?}", 0u32.checked_ilog2());Example
fn main() {
let flags = 0b0110_1000u8;
println!("flags = {:08b}", flags);
println!("set = {} clear = {}", flags.count_ones(), flags.count_zeros());
println!("leading zeros = {}", flags.leading_zeros());
println!("trailing zeros = {}", flags.trailing_zeros());
println!("highest bit position = {}", flags.ilog2());
}Key points
- Use count_ones to count the 1 bits.
- Use count_zeros for the 0 bits.
- Together they always add up to the size of the type.
- Use leading_zeros to find where the value really starts: 0b0000_1010u8 has 4 leading zeros
- Use trailing_zeros to find the lowest set bit: it counts the zeros that come after it
- Use ilog2 for the base-2 logarithm, rounded down: 9u32.ilog2() is 3, because 2^3 = 8 fits into 9 and 2^4 = 16 does not
- ilog2 panics on zero and on negative numbers. checked_ilog2 returns None instead.
In this example, one byte is examined five ways. It holds three set bits and five clear ones, which add up to 8 — the size of a u8. One zero leads it, so its value starts at the second position. Three zeros trail it, so the lowest set bit sits at position 3. ilog2 ties the story together. The highest set bit is at position 6. 2^6 = 64 is the largest power of two that fits in 104.
Note
For a positive number, ilog2 is the position of its highest set bit.
It is the type size minus 1 minus leading_zeros.
That is the same answer, said in one word.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Rust Playground
Exercise
How many set bits does the number 0b1101 have?