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.
Source for wiki NanMedernach version 6
author
cowan
comment
ipnr
98.14.173.81
name
NanMedernach
readonly
0
text
= {{{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-signaling? <obj>)`
Returns `#t` if `<obj>` is a signaling {{{NaN}}}.
`(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}}}.
== 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}}} ===
* allowing computation to continue even in the presence of incorrect computation, instead of aborting with an error.
* to be able to discover what kind of error has been encountered if needed, by propagating a {{{NaN}}} value.
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 ==
* Report invalid sensor values
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.
* Mark undefined values in a vector of reals
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.
time
2012-06-08 13:03:33
version
6