找到平方根到精度

时间:2011-12-20 07:50:30

标签: c++ performance

我刚刚接受各公司在采访中提出的问题。我发现一个是“找到一个精确数字的平方根。函数定义应该是这样的:double getSquareRoot(int num, int precision)”。

我写了一个小函数,它给出了平方根但不关心精度:

double getSquareRoot(int num){
 int num1=0, num2=0;
 for(int i=1 ;; i++){
   if(i*i == num){
    std::cout<<i <<" is the sq root"<<std::endl;
    break;
   }
  else if(i*i > num){
   num2 = i;
   num1 = --i;
   break;
  }
} 
 // in the above for loop, i get the num1 and num2 where my input should lie 
 // between them
 // in the 2nd loop below.. now i will do the same process but incrementing 
 // by 0.005 each time
for(double i =num1;i<(double)num2;i+=0.005)
  {
   if(i*i>= num){
     std::cout<<(double)i <<" is the sq root"<<std::endl;
     break;
   }
 }
}

现在达到精确度,我将不得不做一些调整,如添加if循环和所有。我不喜欢那样。你们能帮助我吗?如果您正在编写代码,请解释。我很感激。

感谢。

这段代码非常不足,并没有解决“直到这个精度”问题的一部分。我只是写它,所以你的家伙不认为我尝试了一下。 这个

4 个答案:

答案 0 :(得分:5)

脱离我的脑海,这有两种方法:

  • 使用interval bisection;你知道错误不超过当前的间隔宽度,所以一旦间隔小于所需的精度就停止迭代。这很简单,但不会像其他方法那样快速收敛。
  • 使用迭代方法,例如Newton's method(用于计算平方根时也称为Babylonian method),并在每次迭代后估算错误。

要估算错误,假设我们正在尝试查找x0 = sqrt(y),以便x0*x0 = y。每次迭代后,我们都有一个候选x = x0 + d,我们想要估算错误d。如果我们平方x,那么我们得到

x*x = x0*x0 + 2*x0*d + d*d
    = y + 2*(x-d)*d + d*d
   ~= y + 2*x*d

放弃d*d条款,因d变得很小而变得非常小。所以我们可以将误差估计为

d ~= (x*x - y) / (2*x)
   = (x - y/x) / 2

并且一旦小于所需的精度就停止迭代。

如果你使用的是巴比伦方法,那么这对迭代计算x = (x + y/x) / 2增加了很少的工作,所以结果就像

double sqrt(double y, double precision)
{
    double x = y;  // or find a better initial estimate
    for (;;) {
        double z = y/x;
        if (std::abs(x-z) < 2*precision)
            return x;
        x = (x+z)/2;
    }
}

答案 1 :(得分:2)

在这种情况下,最好的答案可能是:使用一些大号库,例如GNU MP Bignum。它提供mpf_sqrt和类似的功能。浮点数的默认精度可以通过mpf_set_default_prec设置。

最佳, - Christoph

答案 2 :(得分:2)

在这里查看几种算法:Methods of computing square roots

答案 3 :(得分:0)

这是我的解决方案::

double root(int num)
{
  double l=0,m=num,h=num,om=0;

       while(m-om)
       {
            om=m;
            m=(l+h)/2.0;
            if(m*m < num)
            {
                l = m;             
            }
            else if(m*m > num)
            {
                h=m;
            }
       }
       return m;
 }