I'm trying to write, in CodeBlocks, a recursive function that check if a natural number (a long double) is a perfect square. This function called "Square" takes in input, by reference, the long double S and n (setted in the beginning at 1), a bool T and the long double to compare.

Here the code:

```
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);
}
}
```

And in the main function:

```
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;
}
}
}
```

Sometimes occours this error: "Process returned -1073741571 (0xC00000FD)" (for example when (a = 108 and b = 121) and the program stops. Any help?

Try this:

```
#include <cmath>
bool isPerfectSquare( long num ) {
long root = long(sqrt(float(num)));
return root * root == num;
}
```

You'll get `True`

if `num`

is a perfect square or `False`

if not.

You're probably getting a stack overflow error (which is when you use up the entirety of a thread's stack, and it crashes). If you compile with optimizations enabled, the compiler should be able to optimize `Square`

so that it's tail-recursive, which will prevent the stack overflow error.

That being said, we can make `Square`

shorter and friendlier to optimization by removing the references, and just calculating the multiplication directly (which is very cheap):

```
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);
}
```

With optimization turned on (use the `-O2`

compiler flag for gcc and clang, or `/Ox`

for msvc), **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`

library:```
#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;
}
```

User contributions licensed under CC BY-SA 3.0