在C ++中计算3的平方根

时间:2017-12-04 15:24:38

标签: c++

如何使用以下关系计算C ++中3的平方根?

enter image description here

以下是我的尝试:

#include <iostream>
#include <cmath>


int main(void)
{
    double prevRes(1);
    double res(1 + 1./2);
    short i(2);


    while (abs(prevRes - res) > 1.e-14)
    {
        prevRes = res;

        res = i + 1 / res;

        i = 3 - i;
    }

    std::cout << res << std::endl;

    return 0;
}

该程序永远运行。

4 个答案:

答案 0 :(得分:2)

如果将它与wikipedia进行比较,公式似乎有点不对劲。注意1 +在开始时重复。

接下来,我们可以使用递归函数来执行计算并提供一些迭代。请注意,我们可以使用大的返回值来终止递归(甚至是零,但这需要更多的迭代,因为它在技术上做出了错误的假设)。

最后,我们继续尝试更多迭代,直到错误足够小。

#include <iostream>
#include <limits>
#include <cmath>

double f(int depth, bool odd = true)
{
    if(depth == 0)
        return std::numeric_limits<double>::max();
    return (odd ? 1 : 2) + 1. / f(--depth, !odd);
}

double sqrt3(int depth = 10)
{
    return 1 + 1. / f(depth);
}

int main(void)
{
    int depth{2};
    double prevRes{sqrt3(depth)};
    double res{sqrt3(++depth)};
    while(abs(prevRes - res) > 1.e-14)
    {
        prevRes = res;
        res = sqrt3(++depth);
    }

    std::cout << "Answer is " << res << " at depth " << depth << ".\n";
}

输出:

Answer is 1.73205 at depth 26.

答案 1 :(得分:2)

遗憾的是,这个问题没有得到更多的努力和细节,因此被认真对待。我一直对连续分数的外观和概念感到困惑,但是花时间思考它们并实现它们一直很好。

这个特殊的可以迭代完成。正如@wally所述,问题中显示的连续分数不会收敛到sqrt(3),而是收敛到~1.36603。两个最顶层的系数应为1.注意sqrt(3)〜= 1 +(1 / 1.36603),并且连续分数中的所有系数都交替出现。

因此,如果一个循环从底部向上工作直到交替的连续分数收敛,那么循环之后的另一个计算将给出正确的答案。在每次迭代时,当前值的倒数被加到1或2.初始值可以是任何值。

#include <iostream>
#include <cmath>
#include <limits>

// Calculate square root of 3 with a continued fraction
int main(void) {
  int iterations = 0;
  double epsilon = 1.0e-12; //error bounds
  double prev = 0.0;
  double curr = 1.0; //initial estimate
  double error = curr - prev;

  // Don't show more precision than we have
  std::cout.precision(std::numeric_limits<double>::digits10);

  // Iterate the continued fraction [1;1,2,1,2...]
  // from the bottom up until it converges with errors
  // less than epsilon.
  while (std::abs(error) > epsilon) {
    prev = curr;
    // Unroll the loop with the repeating pattern here
    curr = 2 + (1/curr);
    curr = 1 + (1/curr);

    iterations++;
    error = curr - prev;
    std::cout << "error at iteration " << iterations
              << " was " << error << std::endl;
  }

  // The actual continued fraction we want to evaluate
  // is [1;1,1,2,1,2,...].
  // The two top-level coefficients are 1, so do
  // another half iteration here. 
  curr = 1 + (1/curr);

  std::cout << "sqrt(3) = " << curr << " after "
            << iterations << " iterations" << std::endl;

  return 0;
}

这种策略适用于任何连续的分数,并以重复的系数模式结束。

至于为什么原始代码没有完成,我将把它留给作者弄清楚。打印报表或袖珍计算器会有所帮助。

答案 2 :(得分:1)

double sqrt_of_three(bool adds_two, int rec_depth, int max_rec_depth)
{
    int x;
    if (rec_depth < 2)
        x =  1;
    else 
        x = adds_two ? 2 : 1;
    if (rec_depth < max_rec_depth)
        return x + 1/sqrt_of_three(!adds_two, ++rec_depth, max_rec_depth);
    return x;
}

可以通过估计阈值来调用此方法。

int main()
{
    std::cout << sqrt_of_three(true, 0, 10);
}

这是一个如何递归调用计算3的平方根的函数的示例。现在,您可以通过反复试验手动设置最大递归深度,或者您执行第一种方法所做的操作,并在每次执行后进行检查如果两个不同的最大递归深度之间的值小于某个阈值,则完全递归。

肯定不是找到三个平方根的最有效方法,因为你必须做n*(n-1)/2(其中n是满足你设置的边界的递归深度)总共递归根据你想要收敛到真实结果的距离,这可能会很多。

答案 3 :(得分:1)

使用内置的sqrt函数。

#include <cstdio>
#include <cmath>

int main ()
{
    double param, result;
    param = 1024.0;
    result = sqrt (param);
    printf ("sqrt(%f) = %f\n", param, result );
    return 0;
}