10

在 Common Lisp 中是否有一种独立于实现的方式来表示无穷大或非数字(NAN)?它需要是一个双浮点数,并且具有正值和负值。在 SBCL 中,结果

(apropos "INFINITY")

包括

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

但我需要它在所有实现中都可用。我有一个要编写的包的附录,它可以在所有平台上运行,它需要无穷大和 NAN 的表示。甚至来自另一个库的函数也足够了。

我已经iee-floats加载了,它现在是我图书馆的一部分。我有一个检测数字是否为 NaN 的函数和一个检测数字是否为无穷大的函数;我还没有测试过 NaN,但我的无穷大函数需要数字是双浮点数。SBCL 的SB-EXT:DOUBLE-FLOAT-POSITIVE-INFINITY作品,但我需要它独立于实施。

4

3 回答 3

13

Rosetta Code关于 Infinity 的 Common Lisp 部分的条目说:

Common Lisp 没有指定无穷大值。但是,某些实现可能支持 IEEE infinity。例如,CMUCL 支持IEEE 特殊值。Common Lisp 确实指定实现定义具有最多(和最少)正(和负)值的常量。这些可能因实现而异。

Cliki 列出了一个可能有帮助的ieee-floats包(但请注意它所说的:infinity):

IEEE-Floats提供了一种将 float 和 double-float 类型的值与 IEEE 754(处理器和网络协议通常使用)定义的二进制格式表示相互转换的方法。

该库为常见的 32 位和 64 位格式定义了编码和解码函数,并为其他格式定义了类似函数的宏。默认函数不检测 NaN 或无穷大的特殊情况,但可以生成可以检测的函数,在这种情况下,使用关键字 :not-a-number、:positive-infinity 和 :negative-infinity 来表示它们。

听起来你最好的办法可能是在你想要支持的实现中找到一些 IEEE 值,并编写一个跨平台兼容层 [当然,你应该发布并与他人共享 :)]。

于 2013-10-14T15:34:33.807 回答
2

如果你加载GSLL(在 quicklisp 中),你有 gsl:+positive-infinity+, gsl:+negative-infinity+, 甚至gsl:+nan+. 这些应该可以在可以安装 GSLL 的任何地方工作。

于 2013-10-18T16:26:04.883 回答
2

以下要求禁用浮动陷阱,但是......由于您正在处理此类值,因此无论如何您都需要禁用陷阱。即从标准中考虑这个gem:“浮点陷阱是否发生,以及是否或如何启用或禁用它们取决于实现。因此,符合标准的代码可以为这种情况建立处理程序,但不能依赖于它的信号。”

(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))
于 2017-06-08T21:48:40.753 回答