Previous: notes nan inf, Up: notes nan [Index]
NaN is a special value used as result of a wrong expression. We have seen that the composition of infinities is not always defined; in those cases the result is NaN:
(+ +inf.0 -inf.0) ⇒ +nan.0 (+ -inf.0 +inf.0) ⇒ +nan.0 (- -inf.0 -inf.0) ⇒ +nan.0 (- -inf.0 +inf.0) ⇒ +nan.0 (/ +inf.0 +inf.0) ⇒ +nan.0 (/ +inf.0 -inf.0) ⇒ +nan.0 (/ -inf.0 +inf.0) ⇒ +nan.0 (/ -inf.0 -inf.0) ⇒ +nan.0
also it is:
(div 0 0) ⇒ <error> (/ 0 0) ⇒ <error> (/ 0.0 0) ⇒ +nan.0 (/ 0 0.0) ⇒ +nan.0 (/ 0.0 0.0) ⇒ +nan.0
because, in Mathematics, 0 / 0 is not compliant to the axioms:
(0 / 0) = y ⇒ 0 * y = 0 y is not unique
Special rules were defined so that an arithmetic composition between NaN and another number always returns NaN. This allows us not to mistake a wrong computation for a correct one:
(+ 1 +nan.0) ⇒ +nan.0 (- 1 +nan.0) ⇒ +nan.0 (* 1 +nan.0) ⇒ +nan.0 (/ 1 +nan.0) ⇒ +nan.0
we have to beware, though, that some non–arithmetic function may hide the NaN, and give rise to some surprise:
(max 1 +nan.0) ⇒ 1.0 ; ! the inexact 1!! (min 1 +nan.0) ⇒ +nan.0 ; !?!
Scheme defines a predicate to test if a value is NaN, nan?.
R6RS Scheme mandates that:
(= +nan.0 +nan.0) ⇒ #f (= +nan.0 z) ⇒ #f
for every number z. The first is correct because a wrong computation is not equal, in numerical sense, to another wrong computation.
R6RS Scheme also states that:
(eqv? +nan.0 +nan.0) ⇒ <undefined>
but currently many Scheme implementations do:
(eqv? +nan.0 +nan.0) ⇒ #t (equal? +nan.0 +nan.0) ⇒ #t
notice that, by definition, equal? relies on eqv?. This
allows us to do tests for wrong computations using not only nan?;
this is especially useful when writing test suites (with more
complicated stuff than this):
(check
(list (+ 1 2) (/ 0.0 0.0))
=> '(3 +nan.0))
The behaviour of eqv? and equal? does not reduce our
ability to detect wrong expressions; we can always do:
(let ((v (expression)))
(cond
((= v 1) (some-thing))
((nan? v) (some-other-thing))
(else (yet-another-thing))))
eqv? and equal? just allow us to do (by definition
case relies on eqv?):
(case (expression)
((1 2) (some-thing))
((+nan.0) (some-other-thing))
(else (yet-another-thing)))
(let ((v (expression)))
(cond
((= v 1) (some-thing))
((eqv? v +nan.0) (some-other-thing))
(else (yet-another-thing))))
which, in some situations, is one more possibility to code the logic of a function:
(= (expression1) (expression2))
⇒ <bool> ; true if the results are equal numbers
(eqv? (expression1) (expression2))
⇒ <bool> ; true if the results are equal numbers
; or are both wrong expressions
Previous: notes nan inf, Up: notes nan [Index]