递归函数出现问题(检查数字是否为正整数)

时间:2019-08-07 16:13:27

标签: c++ codeblocks

我正在尝试在CodeBlocks中编写一个递归函数,以检查自然数(长双精度)是否为理想平方。该函数称为“平方”,它通过引用输入长双精度数S和n(以1开头设置),布尔T和要比较的长双精度数。

代码在这里:

void Square(long double& S, long double& n, bool& T,long double k){
        S=S+2*n+1;
        n++;
        if(S==k){
             T=true;
        }

        if(S>k){
            T=false;

        }

        if(S<k){
            Square(S,n,T,k);
        }
}

在主要功能中:

long double S,n,k;

bool T=false;

for(long double b=1;b<50000;b++){

    for(long double a=1;a<b;a++){

        S=1;
        n=1;
        T=false;

        k=12*a*b*b*b-3*a*a*a*a;

        Square(S,n,T,k);

        if(T==true){
            cout<<a<<"    "<<b<<"   "<<k<<endl;
        }
    }
}

有时会发生以下错误:“进程返回了-1073741571(0xC00000FD)”(例如,当(a = 108和b = 121)并且程序停止时。有帮助吗?

2 个答案:

答案 0 :(得分:1)

尝试一下:

#include <cmath>

bool isPerfectSquare( long num ) {
    long root = long(sqrt(float(num)));
    return root * root == num;
}

如果True是一个完美的正方形,您将得到num,否则将得到False

答案 1 :(得分:1)

您可能会遇到堆栈溢出错误(即当您耗尽线程的整个堆栈,并且崩溃时)。如果在启用了优化的情况下进行编译,则编译器应该能够优化Square,使其具有尾部递归性,这将防止堆栈溢出错误。

话虽如此,我们可以通过删除引用,并直接计算乘法(这非常便宜),使Square的优化过程更短,更友好:

bool is_square(long long k, long long n = 0) {
    if(n * n >= k)
        return n * n == k;
    else
        return is_square(k, n + 1);
}

启用优化功能(对于gcc和clang使用-O2编译器标志,对于msvc使用/Ox),this compiles to a simple loop

is_square(long long, long long):
        mov     rax, rsi
        imul    rax, rsi
        cmp     rdi, rax
        jle     .L3
.L2:
        add     rsi, 1
        mov     rax, rsi
        imul    rax, rsi
        cmp     rax, rdi
        jl      .L2
.L3:
        cmp     rdi, rax
        sete    al
        ret

使用cmath库的快速解决方案:

#include <cmath>

bool is_square(long long k) {
    long double real_root = sqrt((long double)k); 
    long long integral_root = llround(real_root);
    return integral_root * integral_root == k;
}