[comp.lang.scheme.c] IEEE-proof float unparsing

max@Neon.Stanford.EDU (Max Hailperin) (09/16/89)

Although C-Scheme has a hook in the number unparser for coping
with funny stuff like NaNs (Not-a-Numbers) and infinities (as
in IEEE-standard floating point), I haven't seen any code to
exploit that.  So, when I generated an overflow on a pmax and
printing out the result went into an infinite loop trying to
normalize infinity to the range 1-9.999..., I decided it was
time to write my own.  I enclose it below in the hopes that it
will be of general use, and also because I hope the MIT Scheme
Team will incorporate it into a future release.  The code also
makes publicly available it's two auxilliary routines, NaN? and
finite?, in the hopes that they will be more generally useful.
Note that this code does no harm (except to performance) on
traditional non-IEEE-fp machines like the VAX.  The first batch
of code is my beta release 7.0.0 runtime/site.scm file, the second
is a replacement for final installation step for use with
release 6.1.2.
=============================================================================
(define (NaN? x)
  (not (= x x)))

(define (finite? x)  ; note that NaNs are not finite, by convention
  (or (zero? x)
      (not (NaN? (/ x x)))))

(define (ieee-proof/float-unparser-hook x)
  (cond ((finite? x)
	 #f)  ; do normal unparsing
	((NaN? x)
	 '(#\# #\[ #\N #\a #\N #\]))
	(else  ; must be +infinity, because sign has already been normalized
	 '(#\# #\[ #\i #\n #\f #\i #\n #\i #\t #\y #\]))))

(lexical-assignment (package/environment (find-package
					  '(runtime number-unparser)))
		    'float-unparser-hook
		    ieee-proof/float-unparser-hook)
=============================================================================
(lexical-assignment (access number-unparser-package system-global-environment)
		    '*special-float-unparser-hook*
		    ieee-proof/float-unparser-hook)
=============================================================================

max@Neon.Stanford.EDU (Max Hailperin) (09/18/89)

I'm embarrassed to say that the finite? routine in my posting is rather
suboptimal.  It's the way it is for obscure historical reasons.  A
much nicer version follows:

(define (finite? x)
  (not (NaN? (- x x))))