## distinguishing usual numbers, infinities and NaN

In a Scheme program, I need to distinguish infinities and NaN values. In Guile, it’s simple, it’s just the functions `inf?` and `nan?`. But when I took another implementation, I got troubles. I spent a lot of time and tried everything — `=`, `eq?`, `equal?`, but nothing helped. Fortunately, after a break, I found a simple universal solution.

Let’s see what happens if we compare (by `<`) the values.

Code:

```
(for-each (lambda (left)
(for-each (lambda (right)
(display (< left right))(display " "))
(list (/ 0.0 0.0) (/ 1.0 0.0) (/ -1.0 0.0) 777))
(newline))
(list (/ 0.0 0.0) (/ 1.0 0.0) (/ -1.0 0.0) 777))
```

The table:

< | NaN +inf -inf 777 ------------------------- NaN | #f #f #f #f +inf | #f #f #f #f -inf | #f #t #f #t 777 | #f #t #f #f

Similar tables can be got for `>` and `=`. With this table, it’s easy to differentiate the type of a variable `x`. For example:

* If it is greater than `-inf` and less that `+inf`, it’s an usual number.

* Otherwise: if it is greater than `-inf`, then it’s `+inf`; if it is less than `+inf`, then it’s `-inf`.

* Otherwise, it’s `NaN`.

The code uses another algorithm of the same style.

```
(define gx:nan? (lambda (x) (not (or (< x 777) (> x -777)))))
(define gx:inf? (lambda (x)
(if (and (< x (/ 1.0 0.0)) (> x (/ -1.0 0.0)))
#f
(not (gx:nan? x)))))
```

Testing:

```
(map gx:inf? (list (/ 0.0 0.0) (/ 1.0 0.0) (/ -1.0 0.0) 777))
===> (#f #t #t #f)
(map gx:nan? (list (/ 0.0 0.0) (/ 1.0 0.0) (/ -1.0 0.0) 777))
===> (#t #f #f #f)
```

June 1st, 2007 at 5:51 am

I’ve got an e-mail reply from Kalle Olavi Niemitalo:

—

Apparently R5RS does not require support for infinities,

but if there is such support, I think these should work:

(define (nan? x) (not (= x x)))

(define (inf? x) (and (nan? (- x x)) (not (nan? x))))

I like how there are no numerals in these.

—

It’s a nice idea, I didn’t thought about it.

Unfortunately, SISC interpreter has a bug. (= (/ 0.0 0.0) (/ 0.0 0.0)) is #t.