C/ c++中的平方根

Square Root in C/C++

本文关键字:平方根 c++      更新时间:2023-10-16

我正试图实现我自己的平方根函数,它只给出平方根的积分部分,例如平方根3 = 1。

我看到了这里的方法,并试图实现

方法
 int mySqrt(int x)
 {
    int n = x;
    x = pow(2, ceil(log(n) / log(2)) / 2);
    int y=0;
    while (y < x)
    {
        y = (x + n / x) / 2;
        x = y;
    }
    return x;
}

上述方法对于输入8失败。而且,我不明白为什么它应该工作。

同样,我也试过这里的方法

int mySqrt(int x)
{
    if (x == 0) return 0;
    int x0 = pow(2, (log(x) / log(2))/2) ;
    int y = x0;
    int diff = 10;
    while (diff>0)
    {
        x0 = (x0 + x / x0) / 2; diff = y - x0;
        y = x0;
        if (diff<0) diff = diff * (-1); 
    }
    return x0;
}

对于第二种方式,对于输入3,循环继续…无限(x0在1和2之间切换)。

我知道两者本质上都是Netwon方法的版本,但我无法弄清楚为什么它们在某些情况下失败以及我如何使它们适用于所有情况。我想我在实现中有正确的逻辑。我调试了我的代码,但仍然找不到一种方法使它工作

这个适合我:

uintmax_t zsqrt(uintmax_t x)
{
    if(x==0) return 0;
    uintmax_t yn = x; // The 'next' estimate
    uintmax_t y = 0; // The result
    uintmax_t yp; // The previous estimate
    do{
        yp = y;
        y = yn;
        yn = (y + x/y) >> 1; // Newton step
    }while(yn ^ yp); // (yn != yp) shortcut for dumb compilers
    return y;
}

返回floor(sqrt(x))

与其用一个估计测试0,不如用两个估计测试。

当我写这篇文章时,我注意到结果估计有时会振荡。这是因为,如果精确结果是一个分数,算法只能在两个最接近的值之间跳转。因此,当下一次估计与上一次相同时终止将防止无限循环。

试试这个

int n,i;//n is the input number
 i=0;
 while(i<=n)
 {
    if((i*i)==n)
    {
        cout<<"The number has exact root : "<<i<<endl;
    }
    else if((i*i)>n)
    {
        cout<<"The integer part is "<<(i-1)<<endl;
    }
    i++;
 }

你可以试试那里的C sqrt实现:

// return the number that was multiplied by itself to reach N.
unsigned square_root_1(const unsigned num) {
    unsigned a, b, c, d;
    for (b = a = num, c = 1; a >>= 1; ++c);
    for (c = 1 << (c & -2); c; c >>= 2) {
        d = a + c;
        a >>= 1;
        if (b >= d)
            b -= d, a += c;
    }
    return a;
}
// return the number that was multiplied by itself to reach N.
unsigned square_root_2(unsigned n){
    unsigned a = n > 0, b;
    if (n > 3)
        for (a = n >> 1, b = (a + n / a) >> 1; b < a; a = b, b = (a + n / a) >> 1);
    return a ;
}

用法示例:

#include <assert.h>
int main(void){
    unsigned num, res ;
    num = 1847902954, res = square_root_1(num), assert(res == 42987);
    num = 2, res = square_root_2(num), assert(res == 1);
    num = 0, res = square_root_2(num), assert(res == 0);
}