【问题标题】:Should I use pow and sqrt or just pow for half integers?我应该对半整数使用 pow 和 sqrt 还是只使用 pow?
【发布时间】:2022-11-30 09:34:52
【问题描述】:

在 C 语言中,我想知道是否存在计算半整数幂的“最佳”方法。简而言之,问题是计算 x^(n/2)(假设 n 是奇数且小得体,x 是一些浮点数)。 sqrt(pow(x, n))pow(x, 0.5 * n) 之间的性能/准确性是否存在重大差异?甚至逆转:pow(sqrt(x), n)

是否有其他一些实现来处理这种特定的半整数情况?

我的第一个想法是您只需使用 pow 并在一次调用中计算整个事情,但我觉得浮点舍入和事情我失去了一些问题的精确度,这是因为这是明确的半整数。我想如果你使用 pow 提升到整数幂并让 sqrt 处理 (1/2) 部分,那么可能会有更好的错误性能。

我还注意到 GSL 具有计算小整数幂的函数;将这些功能与sqrt 结合使用会比仅使用pow 更好吗?

我对使用 C 进行科学编程还很陌生,所以我不确定我什至会去哪里寻找这样的实现,而谷歌并没有真正找到任何东西。

【问题讨论】:

  • 通常更直接的方法更好:在这种情况下为pow()。请记住,当像这样进行数学运算时,sqrt() 最终只是 pow() 的特例。请注意,由于欢乐浮点数学,你需要支付非常仔细的注意你如何四舍五入你的结果。如果您得到像 24.999999993851 这样的值,您可能希望将其解释为 25。
  • 对于整数,如果可以避免的话,我根本不推荐浮点函数。不幸的是,sqrt 有点难以避免,因为它不是那么容易计算(但我敢打赌,找到好的整数算法也相对容易)。
  • 对各种方法的性能和精度运行一些基准测试似乎并不复杂。
  • 在你进入这个兔子洞之前,你有没有可测量的性能问题必须得到解决?如果你不这样做,只需使用pow(),继续生活。如果你有性能问题,那么你需要更深入地挖掘。 pow() 可能不是核心问题。
  • @tadman哈哈,这是一个好点;我绝对只是对一些可能根本不是问题的事情进行了书呆子式的抨击。我没有遇到任何具体问题;我刚刚到了我正在实施这个的地步并认为“一定以前有人想过这个……”

标签: c math floating-point gsl


【解决方案1】:

浮点乘法在典型的现代处理器中是一种相当便宜的操作,当使用基于二进制的浮点格式时,整数乘以 .5 不会引入舍入错误。 (如果表达式写成 n/2,其中 n 是浮点类型,我希望一个像样的编译器将它实现为乘以 .5。但是,可以肯定的是,它可以写成 @987654323 @.)

pow 是一个复杂的例程,但它的执行时间1个pow(x, n)pow(sqrt(x), n)pow(x, n*.5) 之间的差异不太可能受到太大影响。我们通常可以预期 pow(x, n*.5) 是计算 x 的好方法n/2.

sqrt 通常比浮点乘法需要更多的执行时间,并且可能会引入舍入误差。我们可以预期 sqrt(pow(x, n))pow(sqrt(x), n*.5) 至少与 pow(x, n*.5) 一样多的时间,甚至可能更多,但对准确性没有任何好处。

因此,pow(x, n*.5) 是首选。

我还注意到 GSL 具有计算小整数幂的函数;将这些功能与sqrt 结合使用会比仅使用pow 更好吗?

也许。 pow 是一个昂贵的例程,因此即使添加了 sqrt,针对特定权力的定制例程也可以胜过它。这将视情况而定,您可能必须对其进行衡量才能知道。

脚注

1个执行时间实际上不是一个单一的东西。执行一个操作不仅会消耗该操作的时间,而且可能会影响现代处理器中并行执行的其他操作,并且可能会影响后面操作的开始时间,并且它自己的开始时间可能会受到它与先前操作的关系的影响。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    • 2020-04-19
    • 2017-07-14
    • 2011-09-28
    • 2017-09-11
    • 2015-03-01
    相关资源
    最近更新 更多