出于练习的原因,我用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和足够小的数zv = v + z;是一个不可操作的-v不改变。这会让你的循环运行很长时间。
算法不是一个好的选择-您应该查找Newton-Raphson方法。我不相信你的算法能很好地处理像1E-70这样的极端数(而且你已经证明它不能处理像1E+70这样的数)。注意,在大多数支持IEEE浮点的机器上,double的范围可达1E±300或更大。
你能解释一下为什么在一定限度内,不允许手术吗?
浮点数的小数位数是有限的,通常情况下,双精度浮点数的小数位数在16左右。如果添加v = v + z1E+16,则结果为1E-16;没有足够的有效数字来存储额外信息。以1E+16为起点,生成分数5E+10然后z = 1.00.1,…0.01或其左右(朋友之间的数量级是多少?)。当你到处添加最小的值时,你不会改变任何东西。
关于这个主题的规范文档是What Every Computer Scientist Should Know About Floating-Point Arithmetic或者来自ACM的。

关于c - C语言中的平方根算法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40143205/

10-11 20:38