Question

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.

Était-ce utile?

La solution 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.

Autres conseils

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 :)].

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))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top