[comp.arch] SUMMARY of non-IEEE NaN and INF

daw@houxs.UUCP (David Wolverton) (04/29/88)

I asked about non-IEEE implementations that support the concepts
of NaN and infinity (even if not called by those names).

Thanks to all who responded to my request for information, specifically
	From: likewise!uunet!mcvax!cwi.nl!dik (Dik T. Winter)
	From: sun!dgh (David Hough)
	From: mark@hubcap.clemson.edu (Mark Smotherman)
	From: Eugene N. Miya <ihnp4!ames!pioneer.arc.nasa.gov!eugene>
	From: Dick Dunn <rcd@ico.ISC.COM>
	From: Hugh LaMaster <riacs!ames!lamaster@rutgers.edu>
	From: sundc!sun!redwood!rtrauben@seismo.css.gov (Richard Trauben)
	From: Bert Hutchings <likewise!uunet!mcvax!aiva.ed.ac.uk!bert>
	From: jimv%omepd.intel.com@RELAY.CS.NET (Jim Valerio)
	From: ihnp4!iwarp.intel.com!mcg (Steven McGeady)
	From: fisher@market.Alliant.COM (Larry Fisher)
	From: uwvax!astroatc!johnw@rutgers.edu (John F. Wardale)
	From: Radford Neal <uunet!ubc-cs!calgary!vaxb!radford@rutgers.edu>
(This includes only responses received by mail, not USENET followups.)

I slightly edited the responses I received.  I assume that responses were
not private, since I said up front that I would summarize.  The majority 
of respondents identifed the CDC 6600 and cousins as being the model for 
the IEEE arithmetic.  However, see below for some other machines with
interesting characteristics.

Dave Wolverton
ihnp4!houxs!daw

======================EDITED MAIL BELOW==========================

From: likewise!uunet!mcvax!cwi.nl!dik (Dik T. Winter)

The 60-bit Cybers supported them (back from 6600 days).  Also
the Cyber 205, and I believe Cray 1 and XMP and 64 bit Cybers
too.

On the 60-bit Cybers it was optional whether a trap would be
taken with such a number; if desired, a trap was taken when
the number was used; never when it was generated.  If the
option was no trap, full arithmetic on these numbers was defined.
The only useful thing I found with these numbers is that
uninitialized variables where initialized to an infinity, so
use before assignment was trapped (this was Fortran, hence no
'automatic' variables).

----------------------------------------------------------------------

From: sun!dgh (David Hough)

The prototype was CDC 6600, 
which had nan, inf, and signed zero,
but didn't always handle them
consistently.  The default mode
of operation zapped you if you
tried to use a nan.  (they were
called indefinite).

VAX has a reserved operand which,
by default, zaps you if you touch
it, even to move.  Kahan's students
have experimented with exploiting
reserved operands.

----------------------------------------------------------------------

From: mark@hubcap.clemson.edu (Mark Smotherman)

G.A. Blaauw and F.P. Brooks in their chapter on data representation in the
yet-to-be-published manuscript Computer Architecture address this problem
as floating-point range closure.  They identify as one response to closure
the setting of a signal (interrupt or condition code) upon underflow or
overflow.  An alternative design decision is to define specific bit patterns
to represent the extrema.

For Stretch (IBM 7030) they worked out a scheme for partial closure that
included the use of a negligible and an infinity representation (there was
an extra bit in the floating point format for this purpose).  This scheme
was not consistent since there were second-order problems with arithmetic
combinations involving these extrema.

Zuse (of Germany) independently worked out a consistent scheme in which
he solved the second-order closure problem by introducing a third extremum,
namely the indefinite operand (the NaN of IEEE).  Zuse's Z4 also used a
separate bit to indicate extrema.

The CDC 6600 used three extrema; however, the encoding was based on exponent
values.  (They do not indicate whether the CDC 6600 scheme was based on Zuse
or Stretch or was independently derived.)

They conclude, "For the Z4 and the CDC 660, which have no interrupt, the
extrema are highly desirable.  For Stretch the extrema are more of an option;
programming practice, however, has shown that this option is desirable."

----------------------------------------------------------------------

From: Eugene N. Miya <ihnp4!ames!pioneer.arc.nasa.gov!eugene>

The VAL dataflow language has some.
See the papers by McGraw and Weatherall (separate). Weatherall in particular
was a paper on exception handling.

----------------------------------------------------------------------

From: Dick Dunn <rcd@ico.ISC.COM>

I assume you're looking for other-than-IEEE-754 floating forms.

The CDC Cybers, on back to the 6600 (introduced mid-60's, I think designed
around 1964) had such a format.  It had values called "infinite" and
"indefinite", both possibly signed, which correspond to INF and NaN.  The
arithmetic was consistent--for example, +inf * -inf would give -inf; n/0
gave inf with the sign of n (unless n was 0, in which case the result was
indef); inf * 0 gave indef, etc.  If either operand of an operation was
indefinite, the result was indefinite.

Under normal circumstances, you would get an exception when using an
infinite or indefinite operand.  NOTE:  The exception did NOT happen when
generating a bogus result--you could divide by zero just fine and get an
infinite result.  When you tried to use that result in another operation,
you'd get an error.  This was a decidedly bad choice:
    - Programs which generated bogus results but didn't use them ran
      without any error indication.
    - When a program encountered an error, it was often a long way from
      where the bad result was originally generated; bugs were much harder
      to find.
The reason for this bizarre error handling was allegedly that the error was
only detectable very late in the operation cycle; timing and register-reser-
vation prevented reporting it in a more conventional way.

The representation of an infinite value was a number with the maximum
possible exponent.  The representation for indefinite depended on the fact
that the exponent was kept in a biased one's-complement form.  (The bias
was used to make comparison easier.)  This put the -0 exponent value up in
the middle of the range; it was simply ruled out as a valid exponent (since
a normal operation with an in-range result would never generate it) and
used for the exponent to indicate indefinite.  Thus both exceptional number
forms were detectable from their exponents, which were unpacked and
adjusted early in floating point operations.

The machine had instructions to test for infinite and indefinite operands.

----------------------------------------------------------------------

From: Bert Hutchings <likewise!uunet!mcvax!aiva.ed.ac.uk!bert>

You asked in one of the USENET newsgroups for examples of non-IEEE NaNs and
Infinities.  I work on a Prolog system, and Richard O'Keefe  (who knows far
more about Prolog than I ever will)  has contributed some relevant articles
recently to comp.lang.prolog,  showing the difficulty of incorporating IEEE
floating point per se into Prolog.  He mentions a Prolog system which gives
'Infinity' as the result of some arithmetic operations, and I have recently
been told that Arity Prolog gives 'Error' as the result of others.  Clearly
'Infinity' can go away again as a computation proceeds, but 'Error' cannot.

Prolog data is untyped, so it is no problem to store a non-numeric value in
a usually-numeric variable.  The problem arises on comparisons.  'Infinity'
is well-ordered with respect to all other numeric values and to itself, but
'Error' is not.  This is why IEEE had to mandate that any comparison with a
Nan, even with itself, should be _false_ both at the language level and the
underlying machine instruction level - any other result leads eventually to
nonsense.  I believe that any language system  which introduces non-numeric
error results for numeric operations  must, for consistency, adopt the same
rule - a comparison involving the said non-numeric result must be false, in
whichever order,  with consequent restrictions on compilers re-ordering the
program fragment {if A>B then C else D} into {if B=<A then D else C}.

The problems in Prolog are far worse than outlined above,  since it has two
other families of comparison operations, as well as pure arithmetical ones,
but to go into that would be outside the scope of your original query.

----------------------------------------------------------------------

From: jimv%omepd.intel.com@RELAY.CS.NET (Jim Valerio)

In article <845@houxs.UUCP> you ask for experiences with infinities and
NaN(-like) floating-point implementations.  I presume you are explicitly
excluding IEEE-complying implementations, of which there are many.

Infinity is available on CDC machines.  Many machines have reserved operands
that trap; one example is DEC VAX and PDP-11 computers.

Infinities as the results of masked overflow or divide-by-zero are great.
Quiet NaNs are very useful to the hardware implementor (like me!), and
actually complete the number space quite well. Trapping NaNs are interesting
but not much is or has been done with them.  In general, NaNs are not
currently well utilized in software.

However, in this day and age there must be a very good excuse to deviate
from the IEEE standard.

Beware of my bias.  A long-time supporter of the IEEE standard, I'm
responsible for several significant floating-point implementations
recently done by Intel (including the 80387 and the 80960KB).

----------------------------------------------------------------------

From: fisher@market.Alliant.COM (Larry Fisher)

	While I'm sure you'll get alot of feed back from other ex-CDCers
(ex-Control Data employees; there's alot of them), here's my response.

	Beginning with the CDC 6600, and continuing with all its decendents
(other 6000s, 7600, CYBER 70, 170, 170-700 series), had floating point
values labelled INFINITE and INDEFINITE.  Depending on the signs of the
operands used as input to the instruction that produced the INF or IND
result, the sign of the INF (or IND) result was set according to normal
arithmetic rules.

	Basically, a result of INF(INITE) was produced if the magnetude
of the result of an operation would exceed the maximum value that
could otherwise by represented.  Underflow was handled by returning a 
zero (I think only positive zeros were returned --- the machines used
one's complement arithmetic; even floating point values were complemented
to reverse their sign).  Without getting specific, some of the above
mentioned computer models would generate an arithmetic fault only when
an INF or IND value was used as an operand, not when it was generated.
The 7600 (and I believe its CPU-descendants) could generate a fault both
when INF or IND were used as an operand and when they were generated.
The arithmetic faults could be masked by the user via a CPU register.

	The IND(EFINITE) value was produced when the magnetude of the
result was indeterminable, basically as the result of 0/0.  IND would
also be generated whenever one (or both) of the operands for a floating
point instruction was IND.  As with INF, the sign of the result was
based on the sign of the operands, where possible (consider IND - IND:
what's the sign of the result?  +IND was returned by the hardware).

	The hardware reference manuals (something programmers could read),
all included tables showing the results for the operand combinations
of +/-0, +/-x, +/-IND, and +/-INF applied to the various floating point
instructions.  Included in the instruction repertoire were branches for
values being INF or IND. 

	Finally, not to be left out, the FORTRAN compiler would print
I or R for INF or IND (respectively?) when an INF or IND value was
part of the output list of a PRINT or WRITE stmt.  If I recall correctly,
their were even intrinsic functions for checking if a value was IND or
INF.

	Neat, huh?  The IEEE floating point standard was not revolutionary
:-), but it probably does fulfill a need.