Logarithm of integers


I noticed that logarithm functions are implemented only for floating types and not i or u. Is there a reason or just an omission? I suppose I can just convert to a floating type and convert back, but that’s not ergonomic enough.


What would you like 3u32.log(2)? Floor? Ceiling? Truncated? Rounded?


I would expect it to Floor, the same as division. This would be a great feature, IMO. I would use it quite often when working with bits. (How many bits do I need to distribute across N buckets?)


You could always write a macro


For log2, you can use

const fn num_bits<T>() -> usize { std::mem::size_of::<T>() * 8 }

fn log_2(x: i32) -> u32 {
    assert!(x > 0);
    num_bits::<i32>() as u32 - x.leading_zeros() - 1


Really? You want 8u32.log(2) and 15u32.log(2) to both return 3, rather than having 8u32.log(2) return 3 while 9u32.log(2) to 15u32.log(2) return 4?

I suspect you really want Ceiling, not Floor, which gives the correct number of bits for a value that can represent a choice among N items.


Ah! Ceiling it is, then.


While the ceiling/floor of the logarithm might be a very useful function, I’m not sure we’d just want it called log.