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 2

author

aag

comment

Fixed typos and punctuation.

ipnr

216.239.45.4

name

NanMedernach

readonly

0

text

= {{{NaNs}}} library proposal = 

== Library proposal == 
       
`(nan? <obj>)`

`nan?` returns `#t` if `<obj>` is a NaN. 

`(nan)`

Returns a {{{NaN}}}  with an  implementation-defined chosen  payload.  Implementations are free to return different {{{NaNs}}} for each `nan` invocation or not. The reader calls  the `nan` function with no parameter each time it encounters a {{{NaN}}} representation such as "+nan.0".

`(nan <payload>)`

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

`(nan->payload <obj>)`

Returns the payload content 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")))
}}}    

time

2012-06-06 23:29:13

version

2