No compiler would be so stupid as to actually emit a full division for it. But that doesn't mean there's no difference. A signed division by 2 is more complicated than a right shift, you'd have to do something like this:
mov edi, eax
shr eax, 31
add eax, edi
sar eax, 1
Unless you can prove that the number you're dividing by 2 is non-negative. That would require proving hi >= lo
. In a binary search, that might just be feasible (if there's an if (hi < lo) return false;
or something like that before calculating the middle).
Even then the division way still has 3 operations versus 2 of the shift version. Maybe a sufficiently smart JIT compiler can see through that as well, but we're asking more and more of it now.
The old interpreters of the beginning days of Java certainly wouldn't have done any of this, and neither would the first JIT compilers.
So there's a small advantage to writing hi + lo >>> 1
, and there are really no downsides. So why wouldn't they use it?