【问题标题】:representing infinity and NAN independent of implementation代表无穷大和独立于实现的 NAN
【发布时间】:2013-10-22 05:02:56
【问题描述】:

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 有效,但我需要它独立于实现。

【问题讨论】:

标签: common-lisp infinity


【解决方案1】:

Rosetta Code 在Common Lisp section on Infinity 上的条目说:

Common Lisp 没有指定无穷大值。一些实现 但是,可能支持 IEEE infinity。例如,CMUCL 支持IEEE Special Values。 Common Lisp 确实指定了 实现定义constants 与大多数(和最少)积极(和 负)值。这些可能因实现而异。

Cliki 列出了一个可能有帮助的 ieee-floats 软件包(但请注意它对 :infinity 的描述):

IEEE-Floats 提供了一种转换 float 和 定义的二进制格式表示形式的双浮点数 由 IEEE 754(处理器和网络通常使用 协议)。

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

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

【讨论】:

  • @user2862490 我标记了答案community wiki,因为除了快速搜索一些可能的解决方案之外,我并没有做更多的事情,因此任何拥有至少 100 名声望的人都可以编辑它)。希望我们能在这方面取得一些合作成果。
  • 谢谢.....是不是出于好奇才加载每个实现然后找到双浮点无穷大表示一个简单的 if acl then infinity = "something" if sbcl then infinity = "something"那种东西
  • @user2862490 你在问跨平台库会是什么样子吗?它可能有像(defconstant common-numbers:+positive-infinity+ #+sbcl SB-EXT:DOUBLE-FLOAT-POSITIVE-INFINITY #+lispworks lispworks:pos-infinity ...) 这样的定义。 (LispWorks 只是一个例子;我不知道那里是否或如何表示无穷大。)然后人们可以在他们的代码中使用common-numbers:+positive-infinity+,它将在所有支持的实现中工作。
【解决方案2】:

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

【讨论】:

  • from my ?..."我的无穷大函数需要数字是双浮点数 ....SBCL 的 SB-EXT:DOUBLE-FLOAT-POSITIVE-INFINITY 有效,但我需要它独立于实施”如果 GSLL 能够满足该要求,我会很高兴一直在寻找包含它的借口……还有任何减少 GSLL 加载时间的方法我不会一直加载它,因为它太大了,但我很想一直加载它。
  • 我在 ASDF 中看到了一个错误,它会重新编译我加载的所有内容。也许这就是导致您的加载时间长的原因?在任何情况下,您都可以创建一个包含 GSLL 的 save-lisp-and-die 世界,然后您的加载时间不会超过 SBCL 的加载时间。
  • 注意不要在代码中使用 GSL,你不希望开源。 GPL 是病毒式的,会在寒冷的冬夜像 Covid-19 一样感染你的代码。
【解决方案3】:

以下要求禁用浮动陷阱,但是...由于您正在处理此类值,因此无论如何您都需要禁用陷阱。 IE。考虑标准中的这个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))

【讨论】:

    猜你喜欢
    • 2014-09-21
    • 2019-10-11
    • 2020-02-01
    • 2016-10-16
    • 1970-01-01
    • 2015-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多