| Here is the approach taken in Go's sort.Search() Do the sum using signed int. Then cast to unsigned int before the division (i.e., use a non-arithmetic shift low). Then cast back to signed int. func Search(n int, f func(int) bool) int {
// Define f(-1) == false and f(n) == true.
// Invariant: f(i-1) == false, f(j) == true.
i, j := 0, n
for i < j {
h := int(uint(i+j) >> 1) // avoid overflow when computing h
// i ≤ h < j
if !f(h) {
i = h + 1 // preserves f(i-1) == false
} else {
j = h // preserves f(j) == true
}
}
// i == j, f(i-1) == false, and f(j) (= f(i)) == true => answer is i.
return i
}
If you care about stuff like this you may enjoy the puzzle "Upside-Down Arithmetic Shift":https://bugfix-66.com/76b563beb6f4e61801fce4e835be862fb3dbbe... |