10

Is there an implementation independent way of representing infinity or not a number (NAN) in Common Lisp? It would need to be a double float, and have both positive and negative values. In SBCL, the results of

(apropos "INFINITY")

include

SB-EXT:DOUBLE-FLOAT-NEGATIVE-INFINITY (bound)
SB-EXT:DOUBLE-FLOAT-POSITIVE-INFINITY (bound)

but I need it to be available in all implementations. I have an addendum to a package to write that runs on all platforms and it needs a representation of infinity and NAN. Even functions from another library would suffice.

I got iee-floats loaded and it's a part of my library now. I have a function that detects if a number is NaN and one that detects whether a number is infinity; I haven't tested NaN out but my infinity function needs the number to be a double-float. SBCL's SB-EXT:DOUBLE-FLOAT-POSITIVE-INFINITY works but I would need it to be implementation independent.

3 Answers3

13

Rosetta Code's entry on Common Lisp section on Infinity says:

Common Lisp does not specify an infinity value. Some implementations may have support for IEEE infinity, however. For instance, CMUCL supports IEEE Special Values. Common Lisp does specify that implementations define constants with most (and least) positive (and negative) values. These may vary between implementations.

Cliki lists an ieee-floats package that might help (but note what it says about :infinity):

IEEE-Floats provides a way of converting values of type float and double-float to and from their binary format representation as defined by IEEE 754 (which is commonly used by processors and network protocols).

The library defines encoding and decoding functions for the common 32-bit and 64-bit formats, and a macro for defining similar functions for other formats. The default functions do not detect the special cases for NaN or infinity, but functions can be generated which do, in which case the keywords :not-a-number, :positive-infinity, and :negative-infinity are used to represent them.

It sounds like your best best may be to find some IEEE values in the implementations that you want to support, and to write a cross-platform compatibility layer [which, of course, you should then publish and share with others :)].

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
  • @user2862490 I marked the answer [community wiki](http://meta.stackexchange.com/questions/11740/what-are-community-wiki-posts) since I didn't really do much more than a quick Googling for some possible solutions, so anyone with at least 100 reputation can edit it). Hopefully we'll get some collaborative results about this. – Joshua Taylor Oct 15 '13 at 17:21
  • Thanks..... is it out of curiosity just loading each implimentation then finding the double-float infinity representation the a simple if acl then infinity = "something" if sbcl then infinity = "something" kind of thing –  Oct 15 '13 at 17:54
  • @user2862490 Are you asking about what the cross platform library would be like? It might have definitions in it like `(defconstant common-numbers:+positive-infinity+ #+sbcl SB-EXT:DOUBLE-FLOAT-POSITIVE-INFINITY #+lispworks lispworks:pos-infinity ...)`. (The bit with LispWorks is a just an example; I don't know whether or how infinity is represented there.) Then people can use `common-numbers:+positive-infinity+` in their code and it will work in all the supported implementations. – Joshua Taylor Oct 15 '13 at 20:14
2

If you load GSLL (in quicklisp), you have gsl:+positive-infinity+, gsl:+negative-infinity+, and even gsl:+nan+. These should work anywhere that GSLL is installable.

Liam
  • 1,471
  • 1
  • 15
  • 25
  • from my ?..."my infinity function needs the number to be a double-float ....SBCL's SB-EXT:DOUBLE-FLOAT-POSITIVE-INFINITY works but i would need it to be implimentation independent" I would love if GSLL could fill that requirement been looking for an excuse to include it...also any way to cut down on the GSLL load times i don't load it all the time because its so big but i would love to have it loaded all the time. –  Oct 19 '13 at 00:13
  • I've been seeing a bug in ASDF where it recompiles everything I load. Perhaps that is what is causing your long load times? In any case, you can make a world with save-lisp-and-die with GSLL in it, and then your load time no more than the load of SBCL. – Liam Oct 19 '13 at 12:25
  • Be careful not to use GSL in code, you do not wish to open-source. GPL is viral and infects your code like Covid-19 on a cold winter night. – BitTickler Nov 18 '21 at 08:16
2

The following requires that the float traps be disabled, but...since your are processing such values you need to disable traps anyway. I.e. consider this gem from the standard: "It is implementation-dependent whether floating point traps occur, and whether or how they may be enabled or disabled. Therefore, conforming code may establish handlers for this condition, but must not depend on its being signaled."

(eval-when (:compile-toplevel :load-toplevel :execute)
  #+sbcl (sb-int:set-floating-point-modes :traps nil)
  #+cmucl (ext:set-floating-point-modes :traps nil)
  #+linux (cffi:foreign-funcall "fedisableexcept" :int -1))

(defconstant +double+inf+ (* 2 most-positive-double-float))
(defconstant +double-inf+ (* 2 most-negative-double-float))
(defconstant +double-nan+ (/ 0d0 0d0))
Ben Leitner
  • 1,532
  • 1
  • 12
  • 33
kacz
  • 21
  • 1