This site is a static rendering of the Trac instance that was used by R7RS-WG1 for its work on R7RS-small (PDF), which was ratified in 2013. For more information, see Home. For a version of this page that may be more recent, see NanMedernach in WG2's repo for R7RS-large.

Nan­Medernach

medernac
2012-06-09 15:18:54
7nan=? addedhistory
source

NaNs library proposal

Library proposal

(nan)

Returns a NaN}}} with an implementation-defined chosen payload. Implementations are free to return different {{{NaNs}}} for each `nan` invocation or not. If so and as a matter of consistency, {{{NaN}}} representation such as "+nan.0" should also return different {{{NaNs.

(nan <payload>)

Returns a NaN with the given payload as its content. Valid values for <payload> are implementation-dependent.

(nan? <obj>)

Returns #t if <obj> is a NaN.

(nan=? <obj1> <obj2>)

Returns #t if <obj1> and <obj2> are NaNs containing the same payload.

(nan-payload <obj>)

Returns the payload content of <obj> if it is a NaN.

(nan-negative? <obj>)

Returns the sign part of <obj> if it is a NaN.

(nan-signaling? <obj>)

Returns #t if <obj> is a signaling NaN.

Rationale

This library is about NaNs operation handling.

For IEEE Standard for Floating-Point Arithmetic (IEEE 754) implementation there is one NaN}}} concept but many different {{{NaNs}}}. From the purpose of {{{NaNs}}}, we have to be able to distinguish between {{{NaNs}}}. For that effect, {{{NaNs}}} carry a ''payload'' intended to put diagnosis information about what caused a {{{NaN to be produced.

Purposes of NaNs

When the reader reads "+nan.0", it has to choose one particular internal representation for it. It is free to choose one representation shared for all "+nan.0" or to choose a different one each time it encounters another "nan.0". This is what the following means:

(eqv? +nan.0 +nan.0) => unspecified

However the identity of a particular NaN should not be questioned. I mean I think we should have this:

(let ((a +nan.0)) (eqv? a a)) => #t

The following is a desirable behaviour, but I would not push for it into the standard:

(let ((a (/ 0.0 0.0)) (b (sin +inf.0))) (eqv? a b)) => #f

Use cases examples

Instead of returning strange values such as 99999 which could be mistaken for real ones and cause dramatic effects, sensors may use NaNs to report invalid values. A payload may be added to report an additional message.

In order to identify wrong usage of uninitialased vectors, one could fill vectors with NaNs containing indexes in their payloads.

(define (make-reals-vector N) (if (>= N 0) (let ((result (make-vector N))) (let loop ((i 0)) (if (< i N) (begin (vector-set! result i (nan i)) (loop (+ i 1))) result ))) (error "make-float-vector: negative argument")))

Comments by John Cowan

WG1 still hasn't decided what the behavior of eqv? should be when dealing with NaNs. In both draft 6 and the current head, it is unspecified. Therefore it makes sense to me to introduce a new nan=? predicate for seeing if two NaNs have the same payload.