Add bit_len() function

It would be useful to have a function that gets the bit length of unsigned integers. I.e.

0b0 -> 0
0b101 -> 3
0b1110 -> 4

Python has this via 7.bit_length(). Rust almost has it via 7.ilog2(), but it's actually not the same because it panics for 0.

You can do either of these instead:

n.checked_ilog2().map(|n| n + 1).unwrap_or(0)

T::BITS - n.leading_zeros()

However both are worse than n.bit_len() (or .bit_length() if you prefer).

They both produce fairly simple assembly on x86:

first_version:
    bsr     eax, edi
    inc     eax
    test    edi, edi
    cmove   eax, edi
    ret

second_version:
    mov     eax, 63
    bsr     eax, edi
    xor     eax, -32
    add     eax, 33
    ret

I think the second version is probably the better option.

4 Likes

I'd love that in the standard library too!

The best way to get a simple addition like this into the standard library is to file a T-libs-api ACP.

2 Likes

Previously:

8 Likes