在c中实现exp函数的方法是什么?

时间:2013-03-11 23:57:01

标签: c math exp

我想在有限精度下计算exp函数的误差(数据类型是double)。是泰勒系列还是其他特殊算法?

2 个答案:

答案 0 :(得分:9)

通常,实现e x 的最佳方法是调用计算平台提供的exp函数。

如果做不到这一点,实现exp功能很复杂,需要一些深奥的技能。实现通常涉及:

  • 测试各种特殊情况的输入,例如NaN。
  • 将输入乘以特别准备的log 2 e表示,将问题从e x 转换为2 < em> y ,其中 y = x •log 2 e。
  • y 的整数部分移动到浮点编码的指数字段中。
  • 使用minimax polynomial评估 y 的小数部分的指数。
  • 结合上述两个结果。

此外:

  • minimax多项式通常使用特殊软件设计,使用Remez algorithm或类似的东西。
  • 必须以一定的扩展精度完成工作,以便精确计算最终结果。

泰勒系列不适合评估功能,因为它们远离其中心点是不准确的。这意味着它们需要太多的术语来收敛到必要的精度。拥有太多术语不仅需要时间,而且还很难准确地进行算术运算。

答案 1 :(得分:2)

虽然我同意埃里克在回复中所说的大部分内容,但有几点值得补充。我编写了一个工具,除其他外,它允许评估指数到高(用户指定)的精度。

当精度可以变化时,必须采用像系列近似的工具,因为那时没有单个多项式近似就足够了。即便如此,人们可以采用许多技巧。事实上,我对加速这样一个系列的各种技巧感到惊讶。

任何此类努力的一个好的首发参考是哈特,“计算机近似”,这本书遗憾地不容易找到。它提供了许多多项式近似,但也详细讨论了范围缩减技巧。

指数系列本身特别有趣。我在文件HPFMod2.pdf的4.1节中描述了我用于指数的方法,该文件包含在HPF中。

例如,要计算exp(123.456789),可能会尝试直接使用系列,但更好的方法是存储e本身的值。然后我们可以使用范围缩减来计算

exp(123.456789) = exp(1)*exp(2)*exp(8)*exp(16)*exp(32)*exp(64)*exp(.456789)

我们通过重复平方获得2的幂的指数,然后小数部分将适度地快速收敛。 (例如,最终系列中的100位精度需要31个术语。)

但是,假设我们恰好注意到了

123.456789 = 28*ln(10) + 58.9844063961667

现在,我们可以将所需的指数写为:

exp(123.456789) = 10^28 * exp(1)*exp(2)*exp(8)*exp(16)*exp(32)*exp(-0.0155936038332811)

只要我们知道(存储它)ln(10)的值,最后的系列将只需要大约17个术语来实现所需的100位精度。