# [plt-scheme] [ANN] Heist: a Scheme interpreter in Ruby

2009/8/4 James Coglan <jcoglan at googlemail.com>
>*
*>*
*>* 2009/8/4 James Coglan <jcoglan at googlemail.com>
*>*
*>*
*>>*
*>>* 2009/8/4 Chongkai Zhu <czhu at cs.utah.edu>
*>>*
*>>>* I just checked both r5rs and r6rs. Their definition of "/simplest/
*>>>* rational number" is more complex than it can be. Here's PLT's (and another
*>>>* system's) doc of rationalize:
*>>>*
*>>>* ----
*>>>* (rationalize x tolerance) ? real?
*>>>* x : real?
*>>>* tolerance : real?
*>>>*
*>>>* Among the real numbers within (abs tolerance) of x, returns the one
*>>>* corresponding to an exact number whose denominator is smallest. If multiple
*>>>* integers are within tolerance of x, the one closest to 0 is used.
*>>>*
*>>>* ----
*>>>*
*>>>* rationalize(x,dx)
*>>>* yields the rational number with smallest denominator that lies within dx
*>>>* of x.
*>>>*
*>>>* ----
*>>>*
*>>>* in which you can see only to make the denominator smallest is enough. Is
*>>>* this enough hint for you to come to an algorithm?
*>>*
*>>*
*>>* That's certainly enough of a simplification to give me an idea, though I'm
*>>* not sure it'll be very efficient. I'll try to implement it and post here for
*>>* feedback.
*>>*
*>*
*>* This is an attempt at finding the first rational with the smallest
*>* denominator that's in range. Anyone spot anything terribly wrong with it?
*>*
*
Apologies, `ceil` should have read `ceiling`:
(define (rationalize x tolerance)
(cond [(rational? x)
x]
[(not (zero? (imag-part x)))
(make-rectangular (rationalize (real-part x) tolerance)
(rationalize (imag-part x) tolerance))]
[else
(let* ([t (abs tolerance)]
[a (- x t)]
[b (+ x t)]
(do ([i 1 (+ i 1)]
[z '()])
((number? z) z)
(let ([p (ceiling (* a i))]
[q (floor (* b i))])
(if (<= p q)
(set! z (/ (if (positive? p) p q)
i))))))]))
James
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20090804/533a3ddf/attachment.html>