优化sqrt(n) - sqrt(n-1)

ttd*_*ado 7 c optimization mathematical-optimization

这是我每秒多次调用的函数:

static inline double calculate_scale(double n) { //n may be int or double
    return sqrt(n) - sqrt(n-1);
}
Run Code Online (Sandbox Code Playgroud)

像循环一样调用:

for(double i = 0; i < x; i++) {
    double scale = calculate_scale(i);
    ...
}
Run Code Online (Sandbox Code Playgroud)

它太慢了.优化此功能以获得尽可能准确的输出的最佳方法是什么?

参数n:从1开始,几乎不受限制,但主要用于1-10范围内的小数字.它是整数(整数),但它可以是两者,int或者double取决于什么表现更好.

Sto*_*ica 4

您可以尝试用以下近似值替换它

sqrt(n) - sqrt(n-1) == 
(sqrt(n) - sqrt(n-1)) * (sqrt(n) + sqrt(n-1)) / (sqrt(n) + sqrt(n-1)) ==
(n - (n + 1)) / (sqrt(n) + sqrt(n-1)) ==
1 / (sqrt(n) + sqrt(n-1))
Run Code Online (Sandbox Code Playgroud)

对于足够大的情况n,最后一个方程非常接近1 / (2 * sqrt(n))。所以你只需要调用sqrt一次。还值得注意的是,即使没有近似值,最后一个表达式在较大的相对误差方面也更加稳定n

  • 如果我们只是想对大 n 近似 `sqrt(n - 1) == sqrt(n)`,我们应该将原始函数简化为 `return 0;`。;) (6认同)
  • 对于较大的“n”,更好的近似值是“0.5 / sqrt(n - 0.5)”。(这也应该更快,因为它删除了乘法运算。) (4认同)
  • @GManNickG - 是的,好吧:)我意识到在这个建议之后,如果没有其他的话,关于数值稳定性的注释是有必要的。 (2认同)