Logarithm of integers


#1

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.


#2

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


#3

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?)


#4

You could always write a macro


#5

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
}

#6

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.


#7

Ah! Ceiling it is, then.


#8

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