【问题标题】:Implementing basic and special mathematical functions in an arbitrary precision decimal library在任意精度十进制库中实现基本和特殊数学函数
【发布时间】:2016-06-03 14:23:27
【问题描述】:

如果您有一个任意精度的十进制库,但它没有任何基本(例如指数函数、正弦函数)或特殊(例如误差函数、对数积分)数学函数,那么最好的实现方式?

显然,由于大多数这些函数的值是不合理的,因此只有给出指定精度的答案才有意义。所以假设我想计算 erf(x) (例如)到小数点后 50 位,最好的方法是什么?

我的最佳答案是将参数映射到某个合适的范围,然后使用函数的泰勒级数来获得一个(希望)合理快速收敛的答案。我们可以使用诸如泰勒定理之类的东西来限制误差项,但通常,这涉及将阶乘与 10 的幂进行比较(例如,请参阅 Wiki 页面上“一个实变量中的泰勒定理”下的示例Taylor's Theorem),这虽然可行,但似乎冗长。

此外,虽然实现这些功能似乎可行,但在处理此类功能的组合时如何处理精度?例如,如果我们想计算 1000*exp(sqrt(2)) 到 n 位小数,那么我们应该计算中间结果以得到准确的最终答案的精度并不是很明显。

有人知道我可能从哪里开始解决这个问题吗?

【问题讨论】:

  • 我认为自己实现这些繁重的东西根本没有意义。如果可能的话,您应该坚持使用经过良好测试的软件,例如 mpfr,它似乎支持很多这些功能。即使您使用的编程语言不是 C++,我也更愿意包装这个库而不是自己编写(大部分时间)。对于某些语言,还有一些包装器已经存在。
  • 实现小数点后 50 位和小数点后 1000 位将是两个截然不同的事情。在第一种情况下,您可能会使用扩展浮点算术,而在第二种任意精度算术中,包括快速乘法 à la Karatsuba。 Gonnet 和 Baeza-Yates 的书对有效解决方案提供了有趣的见解。 users.dcc.uchile.cl/~rbaeza/handbook/hbook.html(该链接只提供了非常简短的摘要,不公平)。
  • 这是一个很大的区域;很难以 SO 格式给出一个好的答案。我建议您查看 Zimmerman 和 Brent 的“现代计算机算术”一书以获取一些想法,尤其是第 4 章。泰勒级数本身并不够好:您需要将它们与参数缩减技术结合起来进行一些错误分析,以确定您需要什么级别的中间精度。
  • 您还可以查看 Python 的 decimal 模块的 Python 源代码,了解如何实现任意精度正确舍入的 logexpsqrt 等。它并不是非常复杂,但它展示了如何将参数缩减与泰勒级数和整数算术结合起来,以便在每个函数的整个域中在合理的时间内给出结果。来源可以找到here。免责声明:我编写了这些函数。
  • ...如果你会说 Python,mpmath sources 也值得一看。

标签: algorithm math numerical-methods


【解决方案1】:

这个主题非常广泛,每种类型的功能都非常不同。泰勒级数是最后的手段,如果你还想要速度,通常不可用。通常有替代方案(Chebyshev,...),但每种类型的功能都不同,需要不同的方法来获得最佳性能/精度。例如:

  • 基本的测角函数有时可以使用CORDIC 算法求解
  • pow,exp,log 可以通过log2,exp2 解决
  • log2,exp2 可以通过基本数学 (+,-,*,/) 和位 (<<,>>,&,|,^) 函数求解,并使用 sqrt 表示分数位
  • sqrt 可以通过 binary search without multiplication 计算

要更好地了解任意精度的函数之间的差异,请参阅我的任务:

因此,您最好询问有关特定功能实现的问题,而不是针对任何功能的任意方法。

结果的位宽通常被截断为函数属性的合理大小。例如乘法是操作数位的总和,+,- 可以比最大操作数大 1 位,等等...

在选择算法时不要忘记,算法基础复杂度和实际实现复杂度之间存在很大差异。尤其是在任意精度的数字上,因为即使是像加法这样简单的事情也不再是 O(1) ...

【讨论】:

  • 这一切看起来都很棒——它给了我很多开始工作的机会。谢谢!
猜你喜欢
  • 2015-10-29
  • 1970-01-01
  • 1970-01-01
  • 2011-10-21
  • 2013-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多