From: Richard Fateman
Subject: proposal for IEEE floating point and LISP
Date: 
Message-ID: <19lo3sINNce0@agate.berkeley.edu>
Here's a rough proposal for an interface to IEEE 754 binary floating-point
arithmetic modes and exceptions.

THIS DOES NOT MAKE USE OF THE CONDITION PACKAGE DIRECTLY.

The reason the condition handler is not relevant is
that the IEEE standard does not require traps to occur (and
indeed it would be hard for some CPUs to manage a prompt trap
on a floating point exceptional condition).

;;;;;   MODES

;;; rounding direction

;; Inquire what the current rounding direction is:
;; by evaluating (ieee::direction).

;;for SPARC,  the result  is 0=nearest, 1=tozero, 2=positive, 3=negative

;; To change the rounding direction  you type
;; (setf (ieee::direction) 2)   ;etc for positive

;; or by suitable binding of constants  
;; (setf (ieee::direction) ieee::positive)

;;; rounding precision 
;; (IEEE 754 allows you to round to single, double, extended)

;; Inquire what the current rounding precision is
;; by evaluating (ieee::precision) 

;; To change the rounding precision  you type
;; (setf (ieee::precision) 0)   ;etc for extended (on SPARC)
;; (setf (ieee::precision) ieee::extended)

;;;;;;;EXCEPTIONS


;; To can determine the condition of the underflow flag by e.g.
;; (ieee::underflow)   ; t or nil

;; you can change the underflow bit(simulating an underflow) 
;; (setf (ieee::underflow) nil)  ;clears it
;; (setf (ieee::underflow) t)    ;simulates an underflow

;;; similarly for invalid, inexact, division (by zero), and overflow.


;; you can clear all the exception flags by
;; (ieee::clearEX)

;; you can look at all the exception flags by
;; (ieee::getEX)  ;;returns an integer -- the bits are all there..

;; there are  global values (in package :ieee) 
;; for direction, precision, and exceptions.  Bit these
;; are not reliable indicators of the ieee modes or status unless they
;; have been updated by the access functions defined here.

;; you can save and restore the exception bits in one swoop rather
;; than individually by using (setq oldbits (swapEX newbits))

;; you can save and restore the direction indicator by using
;; swapRD, which takes one argument (new direction) and returns
;; previous direction.  Similar functions swapRP and swapEX are
;; available.

;; example

(let (a b old-dir)
  (setq old-dir (swapRD 0))
  (setf (direction) negative)			;round negative
  (setf a (/ 1.0 3.0))
  (setf (direction) positive)			;round positive
  (setf b (/ 1.0 3.0))
  (swapRD old-dir)
  (list a b (- b a)))

;;result is
;;(0.3333333 0.33333334 2.9802322e-8)

;; for your edification:
;; (* 0.25 single-float-epsilon) -->
;; 2.9802322e-8



;; requirements on the arithmetic will now include...
;; if you divide by 0.0, you must set the divide bit, and
;; return an appropriate IEEE number (+ or - infinity of appropriate 
;; precision or not-a-number if it is 0.0 / 0.0.

;; causing a non-continuable trap is a no-no.

(I have code for all of this for SPARC/ Allegro 4.1 Common Lisp.
It is all in Lisp except for 3 foreign-function links to the
math library).

Comments?  

-- 
Richard J. Fateman
·······@cs.berkeley.edu   510 642-1879
From: Barry Margolin
Subject: Re: proposal for IEEE floating point and LISP
Date: 
Message-ID: <19m37vINNdvh@early-bird.think.com>
In addition to global settings for the IEEE modes, I suggest that you
specify binding macros that temporarily set the modes.  The
implementation-dependent expansions of these macros can then interface with
the multithreading that many Lisp implementations have, so that the binding
would only occur in the current thread.  Your implementation using swapRD
and swapEX would have side effects on other threads.

-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar