[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Rationalize



Sorry for broadcasting incorrect information about Gosper's place of employment
-- the comment and the code below were written long ago.  I found the comment
while looking for the code and thought it amusing.  So this isn't Info-Cobol.

I believe the only piece of non-portability in it is the assumption that there
are only two types of floats.

(defun rationalize (x)
  (typecase x
    (rational x)
    (short-float (rationalize-float x short-float-epsilon))
    (long-float (rationalize-float x long-float-epsilon))
    (otherwise (error "~A is not a non-complex number" x))))

(defun rationalize-float (x eps)
  (cond ((minusp x) (- (rationalize (- x))))
	((zerop x) 0)
	(t (let ((y ())
		 (a ()))
	     (do ((xx x (setq y (/ 1.0s0
				   (- xx (float a x)))))
		  (num (setq a (truncate x))
		       (+ (* (setq a (truncate y)) num) onum))
		  (den 1 (+ (* a den) oden))
		  (onum 1 num)
		  (oden 0 den))
		 ((and (not (zerop den))
		       (not (> (abs (/ (- x (/ (float num x)
					       (float den x)))
				       x))
			       eps)))
		  (/ num den)))))))