You are reading content from Scuttlebutt
@aljoscha %xCewsjeq6UTb0ADFN2/owHo/L8X/ljEtYpWld2p+Gg0=.sha256
Re: %3W2iK1uLh

The tripling-based scheme needs base-3 logarithms, which are pretty painful. Your best bet will usually be to convert to a float (64 bit floats can represent integers up to 2^53 precisely, so that should be fine most of the time), use the built-in function for computing arbitrary logarithms, then floor to an integer.

Actually it isn't that bad: floor(log_3(n)/2) only has 41 different results for n between 1 and 2^64, so you can simply do a case distinction:

fn log_3_half(n: u64) -> usize {
    if n == 1 {
        1
    } else if n <= 4 {
        2
    } else if n <= 13 {
        3
    } else if n <= 40 {
        ...

If you can't trust your language implementation to convert this into a binary search, you can do so by hand. You could even do a not-quite-binary search that is biased towards smaller numbers (since most feeds are small and this is invoked in a recursive function with decreasing values).

That mostly eliminates my concerns regarding the tripling construction, I think it is the way to go.

Join Scuttlebutt now