【发布时间】:2016-10-19 23:37:28
【问题描述】:
出于练习的原因,我用 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,程序会冻结。
这里有什么我看不到的吗?
【问题讨论】:
-
您是否使用过调试器来帮助您?它旨在帮助深入研究此类问题。
-
这与使用调试器有什么关系?调试器(即 gdb)可以在终端中运行。
-
对于足够大的数字,
v = v + z;是无操作的 —v不会改变。这会使您的循环运行很长时间。该算法不是一个好的选择。我不相信它适用于像1E-70这样的数字(你已经证明它不适用于像1E+70这样的数字)。请注意,在大多数支持 IEEE 浮点数学的机器上,双精度的范围高达1E±300或更大。 -
浮点数的十进制位数有限——
double通常约为 16 个。如果将1E+16和1E-16相加,则结果为1E+16;没有足够的有效数字来存储额外的信息。您以5E+10为起点;你生成分数z = 1.0然后0.1,0.01,...0.000 000 000 01或附近(朋友之间的数量级是多少?)。当您四处添加最小值时,您最终不会更改任何内容。 -
有关该主题的规范文档是What Every Computer Scientist Should Know About Floating-Point Arithmetic 或来自ACM。并且应该有一个可以重复的问答。我还没有确定。我会将我的 cmets 转换为答案。
标签: c algorithm square-root