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?

1 Like

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

1 Like

You *could* always write a macro

1 Like

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
}
```

7 Likes

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.

2 Likes

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`

.