changing floating point number input.. (was realroots...)
- Subject: changing floating point number input.. (was realroots...)
- From: Robert Dodier
- Date: Mon, 28 Aug 2006 23:37:34 -0600
Richard,
Here's an attempt at a implementation-neutral modification
of nformat to print nan's and inf's. Here's a sample session
(after loading the code) using GCL:
(%i1) obase : 16.;
(%o1) 10
(%i2) a : ?most\-positive\-short\-float;
(%o2) 3.4028235S+38
(%i3) 2 * a;
(%o3) float_inf(1, 69, 800000)
(%i4) -2 * a;
(%o4) float_inf(- 1, 69, 800000)
(%i5) 2 * a - 3 * a;
(%o5) float_nan(- 1, 69, C00000)
(%i6) b : ?most\-positive\-double\-float;
(%o6) 1.7976931348623157E+308
(%i7) 2 * b;
(%o7) float_inf(1, 3CC, 10000000000000)
(%i8) -2 * b;
(%o8) float_inf(- 1, 3CC, 10000000000000)
(%i9) 2 * b - 3 * b;
(%o9) float_nan(- 1, 3CC, 18000000000000)
Printing the sign, exponent, and significand makes the
result theoretically readable ....
FWIW
Robert
PS. Here's the code. Doubtless this can be improved.
(defun significand-bits (x) (nth-value 0 (integer-decode-float x)))
(defun exponent-bits (x) (nth-value 1 (integer-decode-float x)))
(defun float-special-value-p (x)
(and (floatp x)
(let
((max-exponent
(typecase x
(short-float (exponent-bits most-positive-short-float))
(single-float (exponent-bits most-positive-single-float))
(double-float (exponent-bits most-positive-double-float))
(long-float (exponent-bits most-positive-long-float)))))
(= (exponent-bits x) (1+ max-exponent)))))
(defun float-inf-p (x)
(and
(float-special-value-p x)
(= (significand-bits x) (lsh 1 (1- (float-digits x))))))
(defun float-nan-p (x)
(and
(float-special-value-p x)
(not (= (significand-bits x) (lsh 1 (1- (float-digits x)))))))
(let ((save-nformat #'nformat))
(defun nformat (x)
(cond
((float-inf-p x)
(apply save-nformat (list `(($float_inf) ,@(reverse
(multiple-value-list (integer-decode-float x)))))))
((float-nan-p x)
(apply save-nformat (list `(($float_nan) ,@(reverse
(multiple-value-list (integer-decode-float x)))))))
(t
(apply save-nformat (list x))))))