Не писать его вовсе. Проще всего воспользоваться нужными функциями из стандартной библиотеки, например std::set тоже умеет в поиск.
while(r - l > eps), где eps точность. В целочисленном eps=1, а в вещественном всё зависит от точности вычислений.
Проще вынести логику проверки в функцию f(mid, x) — булева функция которая отвечает за переход в первую ветку ил во вторую, в зависимости от mid и x, так как иногда функция проверки сложная, имеет циклы, условия, возможно и ещё бинпоиск ))
Не в целочисленном бинпоиске правую границу можно сделать гораздо больше. Например, r = 1e9 + 228.
Пункт 2 можно сделать проще для дебага, запустив итерации бинпоиска в обычном цикле log2n+2 раз :). В таком случае количество итераций бинпоиска не зависит от l и r.