If this is time-critical then you can use knowledge of the datatypes to make things fast.
If the input is a positive integer (let's say a u64), then log2(x) is almost the index of the last non-1 bit, which you can determine using u64::leading_zeros. In fact log2(x+1) is exactly the index of the last non-1 bit of x. This gives: (playground)
pub fn main() {
for a in 0..10u64 {
let v = (a as f32 + 1.).log2().ceil();
let w = u64::BITS - a.leading_zeros();
println!("{} {} {}", a, v, w);
}
}
outputs
0 0 0
1 1 1
2 2 2
3 2 2
4 3 3
5 3 3
6 3 3
7 3 3
8 4 4
9 4 4
A little more care is needed to handle the sign-bit for signed numbers like i64.
If your number is a floating-point value, there are still some tricks you can play to make things fast, especially if you are willing not to handle NaN, Inf and denormalised numbers.
In particular, for f64 the bit pattern for "normal" numbers is
52 bits of "fraction", 11 bits of mantissa and 1 sign bit. Calling the 11 bits of mantissa e the value of the float is (sign)*(1+fraction/2^52)*2^(e-1023)
So log2(x) = log2(1+fraction/2^52) + (e-1023).
The e-1023 part is an integer, the rest as 0<=log2(1+fraction/2^52)<1, with zero when fraction==0. So ceil(log2(x)) = if fraction==0 {e-1023} else {e-1022}.
This gives us this:
pub fn main() {
for a in -20..20i64 {
let f = (a as f64)/4.0 + 1.0;
let v = f.log2().ceil();
let b: u64 = f.to_bits();
let s = (b >> 63) & 1;
let e = (b >> 52) & ((1<<11)-1);
let frac = b & ((1<<52) -1);
let z = if frac==0 { e as i64 - 1023 } else { e as i64 -1022 };
println!("{:0.2} {:064b} : {:01b} {:011b} {:052b} {} {}", f, b, s, e, frac, z, v);
}
}
which outputs (after trimming out the bit representations)
...
-0.75 ... -2 -2
-0.50 ... -1 -1
-0.25 ... 0 -0
0.00 ... 0 0
0.25 ... 1 1
0.50 ... 1 1
0.75 ... 1 1
1.00 ... 1 1
1.25 ... 2 2
1.50 ... 2 2
1.75 ... 2 2
2.00 ... 2 2
...
Again, this only holds when 1+a is a normal number. You'll need to add conditionals to handle those if you need to. (And you should unless you're sure you don't need to).
Similar tricks can be used for u32 and f32 types.