23

sqrt関数を使わずに平方根を求めるアルゴリズムを探していて、プログラミングに入れてみました。私はC++でこの作業コードに行き着きます

    #include <iostream>
    using namespace std;

    double SqrtNumber(double num)
    {
             double lower_bound=0; 
             double upper_bound=num;
             double temp=0;                    /* ek edited this line */

             int nCount = 50;

        while(nCount != 0)
        {
               temp=(lower_bound+upper_bound)/2;
               if(temp*temp==num) 
               {
                       return temp;
               }
               else if(temp*temp > num)

               {
                       upper_bound = temp;
               }
               else
               {
                       lower_bound = temp;
               }
        nCount--;
     }
        return temp;
     }

     int main()
     {
     double num;
     cout<<"Enter the number\n";
     cin>>num;

     if(num < 0)
     {
     cout<<"Error: Negative number!";
     return 0;
     }

     cout<<"Square roots are: +"<<sqrtnum(num) and <<" and -"<<sqrtnum(num);
     return 0;
     } 

ここで問題は、宣言の反復回数 nCount を初期化することです (ここでは 50 です)。たとえば、36 の平方根を見つけるには 22 回の反復が必要なので問題ありませんが、15625 の平方根を見つけるには 50 回以上の反復が必要です。したがって、50 回の反復後に temp の値が返されます。これに対する解決策を教えてください。

4

10 に答える 10

11

平方根を見つけるためにバビロニアの方法を使用してみませんか。

これが私のコードです:

double sqrt(double number)
{
    double error = 0.00001; //define the precision of your result
    double s = number;

    while ((s - number / s) > error) //loop until precision satisfied 
    {
        s = (s + number / s) / 2;
    }
    return s;
}

幸運を!

于 2016-11-10T12:53:48.907 に答える
2

この質問は古く、多くの回答があることがわかりましたが、シンプルでうまく機能する回答があります..

#define EPSILON 0.0000001 // least minimum value for comparison
double SquareRoot(double _val) {
    double low = 0; 
    double high = _val;
    double mid = 0; 

    while (high - low > EPSILON) {
            mid = low + (high - low) / 2; // finding mid value
            if (mid*mid > _val) {
                high = mid;
            } else {
                low = mid;
            }    
    }   
    return mid;
}

今後のユーザーの参考になれば幸いです。

于 2016-03-03T06:37:09.430 に答える
2

完全に削除しますnCount(このアルゴリズムには多くの反復が必要なルートがいくつかあるため)。

double SqrtNumber(double num)
{
    double lower_bound=0; 
    double upper_bound=num;
    double temp=0;

    while(fabs(num - (temp * temp)) > SOME_SMALL_VALUE)
    {
           temp = (lower_bound+upper_bound)/2;
           if (temp*temp >= num)
           {
                   upper_bound = temp;
           }
           else
           {
                   lower_bound = temp;
           }
    }
    return temp;
 }
于 2013-10-26T20:01:35.320 に答える
1

を使用せずに平方根を求める必要がある場合はsqrt()、 を使用しますroot=pow(x,0.5)

x は平方根を求める値です。

于 2014-09-09T05:36:51.320 に答える
0
//long division method.
#include<iostream>
using namespace std;
int main() {
int n, i = 1, divisor, dividend, j = 1, digit;
cin >> n;
while (i * i < n) {
    i = i + 1;
}
i = i - 1;
cout << i << '.';

divisor  = 2 * i;
dividend = n - (i * i );
while( j <= 5) {
    dividend = dividend * 100;
    digit = 0;
    while ((divisor * 10 + digit) * digit < dividend) {
        digit = digit + 1;
    }
    digit = digit  - 1;
    cout << digit;
    dividend = dividend - ((divisor * 10 + digit) * digit);
    divisor = divisor * 10 + 2*digit;
    j = j + 1;
}
cout << endl;
return 0;
}
于 2015-06-23T19:27:28.393 に答える
-1

以前の回答を見た後、これがあいまいさを解決するのに役立つことを願っています. 以前の解決策と私の解決策の類似点が幻想的である場合、またはルートを解決するこの方法が不明な場合は、ここで見つけることができるグラフも作成しました。

これは、任意の n 乗根を解くことができる作業根関数です。

この質問のために、デフォルトは平方根です

#include <cmath> 
// for "pow" function

double sqrt(double A, double root = 2) {
    const double e = 2.71828182846;
    return pow(e,(pow(10.0,9.0)/root)*(1.0-(pow(A,-pow(10.0,-9.0)))));
}

説明:

グラフはこちら

これは、テイラー級数、対数特性、および少しの代数を介して機能します。

たとえば、次のようにします。

log A = N
   x

*注: 平方根の場合、N = 2; 他のルートについては、1 つの変数 N のみを変更する必要があります。

1) 底を変更し、底の「x」対数関数を自然対数に変換します。

log A   =>   ln(A)/ln(x) = N
   x

2) ln(x) を分離するために再配置し、最終的には 'x' だけにします。

ln(A)/N = ln(x)

3) 両辺を 'e' の指数として設定し、

e^(ln(A)/N) = e^(ln(x))  >~{ e^ln(x) == x }~>  e^(ln(A)/N) = x

4) テイラー級数は "ln" を無限級数として表し、

ln(x) = (k=1)Sigma: (1/k)(-1^(k+1))(k-1)^n

           <~~~ expanded ~~~>

[(x-1)] - [(1/2)(x-1)^2] + [(1/3)(x-1)^3] - [(1/4)(x-1)^4] + . . .

*注: 精度を上げるには、シリーズを続けてください。簡潔にするために、10 ^ 9 を関数で使用します。これは、精度のために、自然対数の級数収束を約 7 桁または 1000 万分の 1 で表します。

ln(x) = 10^9(1-x^(-10^(-9)))

5) ここで、この自然対数の方程式をステップ 3 で得られた単純化された方程式に差し込むだけです。

e^[((10^9)/N)(1-A^(-10^-9)] = nth-root of (A)

6) この実装はやり過ぎに思えるかもしれません。ただし、その目的は、推測や確認を行わずに根を解く方法を示すことです。また、cmath ライブラリの pow 関数を独自の pow 関数に置き換えることもできます。

double power(double base, double exponent) {
    if (exponent == 0) return 1;
    int wholeInt = (int)exponent;
    double decimal = exponent - (double)wholeInt;
    if (decimal) {
        int powerInv = 1/decimal;
        if (!wholeInt) return root(base,powerInv);
        else return power(root(base,powerInv),wholeInt,true);
    }
    return power(base, exponent, true);
}

double power(double base, int exponent, bool flag) {
    if (exponent < 0) return 1/power(base,-exponent,true);
    if (exponent > 0) return base * power(base,exponent-1,true);
    else return 1;
}

int root(int A, int root) {
    return power(E,(1000000000000/root)*(1-(power(A,-0.000000000001))));
}
于 2015-12-18T03:26:36.823 に答える
-1

これは sqrt を見つけるための非常に素晴らしいコードで、元の sqrt 関数よりもさらに高速です。

float InvSqrt (float x) 
{
    float xhalf = 0.5f*x;
    int i = *(int*)&x;
    i = 0x5f375a86 - (i>>1);
    x = *(float*)&i;
    x = x*(1.5f - xhalf*x*x);
    x = x*(1.5f - xhalf*x*x);
    x = x*(1.5f - xhalf*x*x);
    x=1/x;
    return x;
}
于 2014-11-06T20:05:21.283 に答える