出于练习的原因,我用C编写了以下算法:
#include <stdio.h>
#include <stdlib.h>
int main(){
double x=0;
printf("Enter the number: ");
scanf("%lf", &x);
int i = 0;
double v = 0;
double n=0;
int grenze = 12;
double z = 10;
/*
for(i=1; i<(x/2+1); i++){
v=i;
if((v*v) <= x){
n = i;
}
}
v=n;
*/
for(i=1; i<grenze+1; i++){
z = z * 0.1;
while(v*v<x){
v = v + z;
if(v*v<x){
n = v;
}
}
v=n;
}
printf("%.10f\n", n);
}
这工作得很好,但是对于大于某个值的数字(我不知道什么时候开始),例如50.000.000.000,程序会冻结。
有什么我看不到的吗?
最佳答案
对于足够大的数v
和足够小的数z
,v = v + z
;是一个不可操作的-v
不改变。这会让你的循环运行很长时间。
算法不是一个好的选择-您应该查找Newton-Raphson方法。我不相信你的算法能很好地处理像1E-70
这样的极端数(而且你已经证明它不能处理像1E+70
这样的数)。注意,在大多数支持IEEE浮点的机器上,double的范围可达1E±300或更大。
你能解释一下为什么在一定限度内,不允许手术吗?
浮点数的小数位数是有限的,通常情况下,双精度浮点数的小数位数在16左右。如果添加v = v + z
和1E+16
,则结果为1E-16
;没有足够的有效数字来存储额外信息。以1E+16
为起点,生成分数5E+10
然后z = 1.0
,0.1
,…0.01
或其左右(朋友之间的数量级是多少?)。当你到处添加最小的值时,你不会改变任何东西。
关于这个主题的规范文档是What Every Computer Scientist Should Know About Floating-Point Arithmetic或者来自ACM的。
关于c - C语言中的平方根算法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40143205/