The Midpoint That Overflowed — Java Bug Hunt
Inspired by the bug that lived in the JDK's own Arrays.binarySearch for nine years: (low + high) / 2 overflows when the endpoints are large, producing a…
- Language: Java
- Layer: Backend
- Difficulty: Medium
- Concepts: Overflow, Algorithms
- Modelled on: The JDK itself
- Visible tests: huge endpoints do not overflow; small midpoints floor correctly; binary search still finds its targets
- Reward: 50 XP for a complete fix
Briefing
Inspired by the bug that lived in the JDK's own Arrays.binarySearch for nine years: (low + high) / 2 overflows when the endpoints are large, producing a negative midpoint. Joshua Bloch called it "nearly impossible to test for" — unless you test the midpoint itself.
Search.java exposes its midpoint helper. Make it overflow-proof.
Bug report
BUG-JDK5045582 · Reported by: platform (with a famous blog post attached)
midpoint(low, high), both non-negative, low <= high:
- must equal the true mathematical midpoint, floored
- for low=2_000_000_000, high=2_100_000_000 the answer is 2_050_000_000
Observed: that call returns a negative number, and binary search dies with ArrayIndexOutOfBoundsException on gigantic collections.
Logs
[search] midpoint(2000000000, 2100000000) = -97483648The code as shipped
Search.java (editable)
class Search {
static int midpoint(int low, int high) {
return (low + high) / 2;
}
static int indexOf(int[] sorted, int target) {
int lo = 0, hi = sorted.length - 1;
while (lo <= hi) {
int mid = midpoint(lo, hi);
if (sorted[mid] == target) return mid;
if (sorted[mid] < target) lo = mid + 1;
else hi = mid - 1;
}
return -1;
}
}Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More Java bug hunts.