2015-10-23 131 views
0

我正在制作一个C++程序来计算数字的平方根。该程序不使用内置的“sqrt”数学运算。有两个变量,一个用于用户输入的数字,另一个用于该数字的平方根。这个程序不工作非常好,我相信有一个更好的方式来做到这一点:程序来计算平方根C++

这里是我的全码:

#include <iostream> 
using namespace std; 

int main(){ 
    int squareroot = 0; 
    int number; 

    cout << "enter a number sp that i can calculate its squareroot" << endl; 

    cin >> number; 

    while (squareroot * squareroot != number){ 

     squareroot+=0.1; 

} 
cout << "the square root is" << squareroot << endl; 
return 0; 
} 

我知道必须有一个更好的办法。请帮助。通过谷歌浏览,但不了解那里的复杂程序,因为我仍然是一个初学者。

在此先感谢。

+9

这是不是一个真正的编程问题,而是一个数学问题。有几种(高效率和低效率)算法。首先,你应该选择一个并深入研究,直到你详细理解它,然后尝试实现它。 – CompuChip

+3

首先,你需要知道未初始化的局部变量(比如你的'squarertoot'变量)有一个* indeterminate *值,并且使用它们会导致* undefined behavior *。其次,你将'squareroot'声明为一个* integer *变量,你不能添加一个浮点值并且期望它工作正常。 –

+0

取代!=与< – secolive

回答

2

下面给出解释为整数平方根计算:

在数论,正 整数n的整数平方根是正整数米这是最大的整数小于 或等于n的平方根

该方法的开始是好的,但需要一些修正,使其工作:

  1. 您正在使用int工作要添加1至squareroot不是0.1

  2. 要停止你的计算,当你squareroot * squareroot等于或大于number更大

    。想想情况是数字是26,你没有一个整数乘以26。

  3. 在数量等于26的情况下,你想返回5还是6?您while循环后的squareroot值将是6,所以你可能需要将其扭转到5(如果squareroot * squarerootnumber不同)

下方为例:

#include <iostream> 
using namespace std; 

int main(){ 
    int squareroot = 0; 
    int number; 

    cout << "enter a number sp that i can calculate its squareroot" << endl; 

    cin >> number; 

    while (squareroot * squareroot < number){ 
     squareroot+=1; 
    } 

    if (squareroot * squareroot != number) --squareroot; 

    cout << "the square root is" << squareroot << endl; 
    return 0; 
} 

下面更高效以及使用二分搜索原理计算平方根的优雅方式。 O(日志(n))的

int mySqrt(int x) { 
    if (x==0) return 0; 
    int left = 1; 
    int right = x; 
    int res; 

    while (left <= right) { 
     int mid = left + ((right-left)/2); 
     if (mid<=x/mid){ 
      left = mid+1; 
      res=mid; 
     } 
     else { 
      right=mid-1; 
     } 
    } 

    return res; 
} 
+5

我相信只给OP一个解决方案并不能真正帮助他们。也许更好的方法是指出为什么他们的代码不工作,然后指出他们如何改变它的正确方向? – Default

+1

但结果不一定是整数。 – user1095108

+0

@ user1095108你是对的上述解释只适用于整数平方根计算 –

1

该函数将计算平方根的地板如果A是不是一个完美的square.This功能基本上都采用你知道二进制search.Two事情事先是,一些平方根将小于或等于该数字,它将大于或等于1.因此,我们可以在该范围内应用二进制搜索。下面是我的实现。让我知道如果你不明白代码中的任何内容。希望这有助于。

int sqrt(int A) { 
    if(A<1)return 0; 
    if(A==1)return 1; 

    unsigned long long start,end,mid,i,val,lval; 
    start = 1; 
    end = A; 
    while(start<=end){ 
     mid = start+(end-start)/2; 
     val = mid*mid; 
     lval = (mid-1)*(mid-1); 

     if(val == A)return mid;  
     else if(A>lval && A<val) return mid-1; 
     else if(val > A)end = mid; 
     else if(val < A)start = mid+1; 
    } 
} 
+3

我相信只给OP一个解决方案并不能真正帮助他们。也许更好的方法是指出为什么他们的代码不工作,然后指出他们如何改变它的正确方向? – Default

+0

是的你是绝对正确的,但问题是要求可能更好的方式,这就是为什么建议更好的方式。我认为不知道不同的方法没有伤害。也许我不应该发布代码只是建议的方法。 – Khatri

1

此功能使用区间套(未经测试),你可以定义精度:

#include <math.h> 
#include <stdio.h> 

double mySqrt(double r) { 
    double l=0, m; 
    do { 
    m = (l+r)/2; 
    if (m*m<2) { 
     l = m; 
    } else { 
     r = m; 
    } 
    } 
    while(fabs(m*m-2) > 1e-10);  
    return m; 
} 

https://en.wikipedia.org/wiki/Nested_intervals

+5

我相信只给OP一个解决方案并不能真正帮助他们。也许更好的方法是指出为什么他们的代码不工作,然后指出他们如何改变它的正确方向? – Default

1

与您的代码的问题是,它只能如果平方根的数字恰好是N * 0.1,其中N是一个整数,这意味着如果答案是1.4142而不是1.400000000,那么您的代码就会失败。有更好的方法,但它们都更复杂,并使用数值分析来近似答案,其中最简单的就是牛顿 - 拉夫逊方法。

您可以使用下面的函数,该函数使用Newton-Raphson方法找到根,如果您需要更多关于Newton-Raphson方法的信息,请查看this维基百科文章。如果你需要更好的准确性 - 但性能更差 - 你可以减少'0.001'到你的比较,或者如果你想要更好的性能但更少的准确性,可以增加它。

float mysqrt(float num) { 
    float x = 1; 

    while(abs(x*x - num) >= 0.001) 
     x = ((num/x) + x)/2; 

    return x; 

} 

,如果你不希望导入math.h您可以编写自己的abs()

float abs(float f) { 
    if(f < 0) 
     f = -1*f; 
    return f; 
}