【问题标题】:Fast n-th Root in Java [duplicate]Java中的快速第n个根[重复]
【发布时间】:2017-03-08 14:35:19
【问题描述】:

在我的 Java 程序中,我必须经常计算 a^b,其中 a ≥ 00 ≤ b 。我对Math.pow(a, b)的速度不满意。有没有可能比Math.pow 更快的算法(以一定的准确性为代价)?

【问题讨论】:

  • 可能是泰勒级数的较短部分 (stackoverflow.com/questions/4453421/…)?根据应用程序,缓存结果可能有用
  • 如果可以使用exp(b*log(a)) 或其基础 2 变体,您可能会获得更快的结果。这在某些情况下会产生明显的浮点错误,但避免了pow 的更专业版本为减少这些错误而包含的开销。
  • 你有更多关于这些 a 和 b 分布的信息吗?你可以预先计算表吗?难道没有一种解决方法可以避免计算这些幂的需要吗? ...更多上下文很有用。
  • 您可以尝试以下方法。 y = a^b = (m * 2^e)^b = m ^b * 2^(eb) = m^b * 2^(eb - E) * 2^E其中,E = Nearlyint(eb) 和 |eb-E| link

标签: java math numerical-methods


【解决方案1】:

您需要精确的结果,还是只需要一个近似值?

如果一个精确的结果:这很难。

如果您只想要一个近似值:尝试使用第 N 个根算法进行固定点迭代 as described on wikipedia

然后,您可以浪费为您的第 n 根近似值使用您认为适合您的应用程序的尽可能多的时钟周期。

但我猜Math.pow 已经在为你做这件事了。如果你想做得更快,你必须投入一些艰苦的工作。即使在 C(我比 Java 更了解)中,我认为编写该固定点迭代的 非常快的变体 也不是最简单的任务(如果我一直在进行 n 次根计算,他们是绝对的瓶颈,我会求助于多线程,如果可能的话,用 SIMD/AVX 指令做很多工作——甚至是 OpenCL/CUDA)。

【讨论】:

  • 我也喜欢@uzr 链接的问题。问题本身和公认的答案涉及整数幂运算,这在您的情况下实际上并没有那么有用。 但是用户“sbi”关于“突破性加速”的观点非常好并且非常适用于任何程序优化案例 - 并且可能值得您考虑。
  • 很好地提到了 OpenCL 和 CUDA。这将是我的建议。
【解决方案2】:

我相信很难找到比 Java 中的标准数学库更好的数学优化库。

也许您应该看看可以在您的算法中进行的其他优化,例如缓存频繁值,以便它们可以重复使用而不是再次计算,从而减少计算次数。

如果它的关键任务是非常快速地找到第 n 个根,那么您可能应该考虑另一种语言,它的执行时间可能比 Java 更快,或者可以更有效地执行电源操作。

即使进行的实验是在C 中完成的,这也可能很有趣 What is more efficient? Using pow to square or just multiply it with itself?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-04
    • 2019-11-29
    • 2010-10-30
    • 1970-01-01
    • 2015-08-31
    • 1970-01-01
    • 1970-01-01
    • 2016-08-18
    相关资源
    最近更新 更多