As long as you're bit-twiddling (a popular pastime in some circles) why not go all the way? I don't know if there's any efficiency to be gained, but I think it actually makes the algorithm a little clearer.

def bitBinSearch(f: Long => Boolean): Option[Long] = { var n = Long.MinValue var p = 0L var t = n >>> 1 while (t > 0) { if ( f(n|t) ) n |= t if ( f(p|t) ) p |= t t >>= 1 } List(p,n).find(f) }

Of course, if you go recursive you can eliminate those nasty var s.

import scala.annotation.tailrec @tailrec def bitBinSearch( f: Long => Boolean , n: Long = Long.MinValue , p: Long = 0L , t: Long = Long.MinValue >>> 1 ): Option[Long] = { if (t > 0) bitBinSearch(f , if (f(n|t)) n|t else n , if (f(p|t)) p|t else p , t >> 1 ) else List(p,n).find(f) }

Again, probably not more efficient, but perhaps a bit more Scala-like.

UPDATE

Your comment about Int/Long got me wondering if one function could do it all.

After traveling down a few dead-ends I finally came up with this (which is, oddly, actually pretty close to your original code).

import Integral.Implicits._ import Ordering.Implicits._ def bitBinSearch[I](f: I => Boolean)(implicit ev:Integral[I]): Option[I] = { def topBit(x: I = ev.one):I = if (x+x < ev.zero) x else topBit(x+x) var t:I = topBit() var p:I = ev.zero var n:I = t+t while (t > ev.zero) { if ( f(p+t) ) p += t if ( f(n+t) ) n += t t /= (ev.one+ev.one) } List(p,n).find(f) }

This passes the following tests.