docs: function binSearchSolve(f, y, a, b) {
           var mid, vmid, niters;
  
           a = inferEndpoint(f, y, true, a);
           b = inferEndpoint(f, y, false, b);
  
           if (f(a) > f(b)) {
              return binSearchSolve(function(x) { return -f(x); }, -y, a, b);
           }
  
           if (utils.relativelyCloseTo(f(a), y)) { return a; }
           if (utils.relativelyCloseTo(f(b), y)) { return b; }
  
           if (f(a) > y || f(b) < y) {
              throw new Error('Binary search: Desired value not between endpoint values.');
           }
           niters = 0;
           while (niters < utils.maxSteps) {
              mid = (a + b) / 2;
              niters += 1;
              vmid = f(mid);
              if (utils.relativelyCloseTo(a, b) &&
                  utils.relativelyCloseTo(vmid, y)) {
                return mid;
              }
              if (vmid < y) {
                 a = mid;
              } else {
                 b = mid;
              }
           }
           throw new Error('Binary search: Too many iterations');
        }