【问题标题】:Implementing the square root method through successive approximation通过逐次逼近实现平方根法
【发布时间】:2016-04-08 13:27:37
【问题描述】:

通过逐次逼近确定平方根是使用以下算法实现的:

  1. 首先猜测平方根是 x / 2。将这个猜测称为 g。

  2. 实际平方根必须位于 g 和 x/g 之间。在逐次逼近的每一步,通过平均 g 和 x/g 生成一个新的猜测。

  3. 重复步骤 2,直到 g 和 x/g 的值在硬件精度允许的范围内尽可能接近。在 Java 中,检查这种情况的最佳方法是测试平均值是否等于用于生成它的任何一个值。

真正让我困惑的是第三步的最后一句话。我是这样解释的:

private double sqrt(double x) {
    double g = x / 2;
    while(true) {
        double average = (g + x/g) / 2;
        if(average == g || average == x/g) break;
        g = average;
    }

    return g;
}

这似乎只会导致无限循环。我完全遵循算法,如果平均值等于 g 或 x/g(用于生成它的两个值),那么我们就有答案了吗?

【问题讨论】:

  • 你用的是什么输入法?它似乎对我来说终止了......
  • 以 2.23606797749979 为我终止
  • @kevmo314 好的,这很奇怪。我不知道为什么它没有为我终止。
  • 也许我不应该使用 == 来比较双打?

标签: algorithm square-root


【解决方案1】:

为什么有人会使用这种方法,因为他们可以简单地使用 (2n^2) = 4n^2 和 (n + 1)^2 = n^2 + 2n + 1 的公式来填充每个位尾数,然后将指数除以 2,将尾数乘以 2 当且仅当指数与 2 的模数等于 1?

【讨论】:

  • 考虑编辑您的问题以将“you”更改为“You”并删除它之前的单词。这会让你的答案更好。
【解决方案2】:

要检查 g 和 x/g 是否与硬件允许的一样接近,请查看相对差异并进行比较 它与您的浮点格式的 epsilon 一起使用。如果它在 epsilon 的小整数倍范围内,则可以。

x和y的相对差异,见https://en.wikipedia.org/wiki/Relative_change_and_difference

32 位 IEEE 浮点数的 epsilon 约为 1.0e-7,与此处的其他答案之一一样,但该答案使用的是绝对差异而不是相对差异。

实际上,这意味着:

 Math.abs(g-x/g)/Math.max(Math.abs(g),Math.abs(x/g)) < 3.0e-7

【讨论】:

    【解决方案3】:

    永远不要比较浮点值是否相等。结果不可靠。

    像这样使用 epsilon:

    if(Math.abs(average-g) < 1e-7 || Math.abs(average-x/g) < 1e-7) 
    

    您可以将 epsilon 值更改为您需要的任何值。可能最好的是与原始 x 相关的东西。

    【讨论】:

      猜你喜欢
      • 2016-03-15
      • 2019-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-06
      • 1970-01-01
      相关资源
      最近更新 更多