; find the nearest prime

(define (primes n)
  (let ((sieve (make-vector n #t)) (ps (list)))
    (do ((p 2 (+ p 1))) ((= n p))
      (when (vector-ref sieve p)
        (set! ps (cons p ps))
        (do ((i (* p p) (+ i p))) ((<= n i))
          (vector-set! sieve i #f))))
    (list->vector (reverse ps))))

(define ps (primes 542))

(define (bsearch x xs)
  (let loop ((lo 0) (hi (- (vector-length xs) 1)))
    (let ((mid (+ lo (quotient (- hi lo) 2))))
      (cond ((< hi lo)
              (if (< (- (vector-ref xs hi) x)
                     (- x (vector-ref xs lo)))
                  (vector-ref xs lo)
                  (vector-ref xs hi)))
            ((< x (vector-ref xs mid)) (loop lo (- mid 1)))
            ((< (vector-ref xs mid) x) (loop (+ mid 1) hi))
            (else (vector-ref xs mid))))))

(define (find-prime x) (bsearch x ps))

(display (find-prime 123.7)) (newline)
(display (find-prime 4)) (newline)