用C递归计算整数sqrts

时间:2018-05-20 04:16:15

标签: c recursion int bitwise-operators square-root

我调整了一些我发现here的python代码来计算数字的sqrt,如果它使用按位运算作为整数存在的话。这是我的代码。

int ft_sqrt(int nb){
    int smallcandidate;
    int largecandidate;

    if (nb < 0){
        return (0);
    }else if (nb < 2){
        return (nb);
    }else{
        smallcandidate = ft_sqrt(nb >> 2) << 1;
        largecandidate = smallcandidate + 1;

        if (largecandidate * largecandidate > nb){

            return (smallcandidate);
        }
        else{
            return (largecandidate);
        }
    }
}

这适用于我测试的每个数字(在整数可以容纳的范围内),除了3.为什么会这样?我该如何解决?

1 个答案:

答案 0 :(得分:0)

很抱歉,您最好使用迭代函数,因为您看到递归是最终递归,可以折叠为while循环。您的算法是:

#include <stdio.h>

unsigned isqrt(unsigned x)
{
    unsigned quot = 1, mean = x; /* isqrt must be between these two */
    /* we begin with extreme numbers and for each pair of (quot,mean),
     * the first, below the square root, and the other above, we get 
     * mean value of the two (lesser than previous) and the
     * quotient (above the prev. value, but still less than the 
     * square root, so closer to it) to get a better approach */
    while (quot < mean) {
        mean = (mean + quot) >> 1;
        quot = x / mean;
    }
    /* quot is always <= mean so finally it should be the same,
     * we can return quot or mean, indistinctly. */
    return mean;
}

int main() /* main test function, eliminate to use the above. */
{
    unsigned n;
    while (scanf("%u", &n) == 1) {
        printf("isqrt(%u) ==> %u\n", n, isqrt(n));
    }
}

修改

该算法基于几何平均值总是比算术平均值更接近1的事实。所以我们采用两个近似值(源数和1,因为它们的几何平均值是平方根)然后我们计算它们的算术平均值(所以获得的值在两者之间,因此,更接近几何平均值)然后我们将原始值除算术平均数,因此两个aproximations乘以原始数据(并且它们的几何平均值也是平方根)。因为,在每个循环中,算术平均值更接近几何平均值,因此必须是商(因此几何平均数的商),导致两个数字更接近平方根。我们继续算法,直到两个数字相等(a / sqrt(a) = sqrt(a)(sqrt(a) + sqrt(a))/2 = sqrt(a)),或者由于舍入误差,它们会交叉。 ---这发生在整数---