我正在尝试在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)并且程序停止时。有帮助吗?
答案 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;
}