1 | | = {{{NaNs}}} library proposal = |
2 | | |
3 | | == Library proposal == |
4 | | |
5 | | `(nan)` |
6 | | |
7 | | 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}}}. |
8 | | |
9 | | `(nan <payload>)` |
10 | | |
11 | | Returns a {{{NaN}}} with the given payload as its content. Valid values for `<payload>` are implementation-dependent. |
12 | | |
13 | | `(nan? <obj>)` |
14 | | |
15 | | Returns `#t` if `<obj>` is a {{{NaN}}}. |
16 | | |
17 | | `(nan=? <obj1> <obj2>)` |
18 | | |
19 | | Returns #t if <obj1> and <obj2> are {{{NaNs}}} containing the same payload. |
20 | | |
21 | | `(nan-payload <obj>)` |
22 | | |
23 | | Returns the payload content of `<obj>` if it is a {{{NaN}}}. |
24 | | |
25 | | `(nan-negative? <obj>)` |
26 | | |
27 | | Returns the sign part of `<obj>` if it is a {{{NaN}}}. |
28 | | |
29 | | `(nan-signaling? <obj>)` |
30 | | |
31 | | Returns `#t` if `<obj>` is a signaling {{{NaN}}}. |
32 | | |
33 | | |
34 | | == Rationale == |
35 | | |
36 | | This library is about {{{NaNs}}} operation handling. |
37 | | |
38 | | 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. |
39 | | |
40 | | |
41 | | === Purposes of {{{NaNs}}} === |
42 | | |
43 | | * allowing computation to continue even in the presence of incorrect computation, instead of aborting with an error. |
44 | | |
45 | | * to be able to discover what kind of error has been encountered if needed, by propagating a {{{NaN}}} value. |
46 | | |
47 | | |
48 | | 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: |
49 | | |
50 | | {{{ |
51 | | (eqv? +nan.0 +nan.0) => unspecified |
52 | | }}} |
53 | | |
54 | | However the identity of a particular {{{NaN}}} should not be questioned. I mean I think we should have this: |
55 | | |
56 | | {{{ |
57 | | (let ((a +nan.0)) (eqv? a a)) => #t |
58 | | }}} |
59 | | |
60 | | The following is a desirable behaviour, but I would not push for it into the standard: |
61 | | |
62 | | {{{ |
63 | | (let ((a (/ 0.0 0.0)) (b (sin +inf.0))) (eqv? a b)) => #f |
64 | | }}} |
65 | | |
66 | | == Use cases examples == |
67 | | |
68 | | * Report invalid sensor values |
69 | | |
70 | | 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. |
71 | | |
72 | | * Mark undefined values in a vector of reals |
73 | | |
74 | | In order to identify wrong usage of uninitialased vectors, one could fill vectors with {{{NaNs}}} containing indexes in their payloads. |
75 | | |
76 | | {{{ |
77 | | (define (make-reals-vector N) |
78 | | (if (>= N 0) |
79 | | (let ((result (make-vector N))) |
80 | | (let loop ((i 0)) |
81 | | (if (< i N) |
82 | | (begin |
83 | | (vector-set! result i (nan i)) |
84 | | (loop (+ i 1))) |
85 | | result ))) |
86 | | (error "make-float-vector: negative argument"))) |
87 | | }}} |
88 | | |
89 | | |
90 | | == Comments by John Cowan == |
91 | | |
92 | | I endorse this proposal. |
| 1 | See [[wiki:FloatCLMedernach]] |