【问题标题】:Decimal expansions using lazy sequences in Clojure在 Clojure 中使用惰性序列进行十进制扩展
【发布时间】:2013-11-28 01:08:48
【问题描述】:

在 Clojure 中是否有使用惰性序列表示十进制扩展的包?

例如语法类似

(defn r `(B N x_1 x_2 x_3 ...))

可以以 B 为基数表示实数 r,并带有十进制扩展(以数学表示法)

r = N . x_1 x_2 x_3 ...

具有整数有效位 N 和十进制数字 0 ≤ x_i ≤ B-1

如果该类型足够“智能”,它可以处理实数的不同十进制扩展作为有效输入,例如(10 0 9 9 9 ...)(10 1),并始终以后一种形式输出十进制扩展。它还应该能够处理溢出的数字,例如将(10 0 15) 减少到(10 1 5)

使用实数的惰性序列表示而不是通常的十进制扩展是否有任何障碍?我不知道与浮点相比它的效率如何,但它可以方便地进行涉及实数的严格精确算术。例如,我认为有些算法可以递归计算 π 和 e 的小数展开式。

【问题讨论】:

  • 在检查了 Clojure Toolbox 中的数学部分并在 Clojars 中进行了一些查询之后,我找不到任何可以执行此操作的库,但这听起来是一个不错的项目 :)
  • 同意,听起来像是一个很酷的图书馆的机会。

标签: math clojure floating-point


【解决方案1】:

TL;DR

简短的回答是不,没有这样的图书馆,我怀疑永远不会有。可以将数字计算到比 IEEE 双精度更高的精度,但是通过表示为单个数字序列来这样做在内存方面是非常浪费的,并且在一般情况下不可能完全懒惰地这样做。例如,按术语懒惰地计算(+ '(0 9 0 ... ) '(0 9 1 ...))

长版

当将实数或表达式的值“计算”(近似)到机器精度时,计算的运算是将所需表达式的 taylor series 扩展为 N 项,直到第 N+1 项的值是小于机器精度,此时近似被中止,因为硬件约定不能表示更多信息。

通常您只会看到 32 位和 64 位 IEEE 浮点标准,但 IEEE 浮点规范扩展到了高达 128 位的表示形式。

为了争论,我们假设某人扩展了clojure.core.math 以具有某种表示arbitrary-precision-number,这是一个软件浮点实现,以支持ByteArray,通过协议出现的所有意图和目的都是正常java.lang.Number。这种表示所实现的只是将机器 epsilon(表示误差限制)推到甚至低于 IEEE DOUBLE/64 提供的 5x10e-16 界限。构建这样一个软件浮点系统是完全可行的,并且经过了相对较好的探索。但是我不知道它的 Java/Clojure 实现。

真正的任意精度是不可能的,因为我们有有限的内存机器可以构建,因此在某些时候我们必须在性能、内存和精度上做出妥协。鉴于某些库可以在某些时候正确且通常将任意泰勒级数评估表示为十进制数字序列,我声称由于需要执行,对此类任意数字的绝大多数操作将被截断到某个精度 P与浮点或双精度等固定精度表示进行比较,因为它们是浮点表示的行业标准。

要将这口井真正吹出水面,在 1 光年的距离内,1e-100 度的角度偏差将导致大约 1.65117369558e-86 米的导航误差。这意味着现有的 5x10e-16 具有 IEEE DOUBLE/64 的机器 epsilon 甚至对于星际导航也是完全可以接受的。

正如您提到将 Pi 或其他有趣序列的小数项计算为惰性序列一样,这里可以取得进展只是因为目标是序列/序列的表示和研究,而不是加法、减法、乘法等在两个或多个这样的表示之间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 2010-12-08
    相关资源
    最近更新 更多