我编写的求平方根算法输入5等数值时进入死循环,是什么原因?
问题原因分析
- 核心死循环原因:
raiz_exata函数的base和teto参数定义为int类型,每次循环中把浮点型的media赋值给这两个变量时,会发生整数截断,丢失小数部分,导致上下界无法正常收敛。比如求5的平方根时,初始base=2、teto=3,第一次计算media=2.5,2.5²=6.25>5,你尝试把teto设为2.5,但int类型的teto会被截断为2,接下来base和teto都等于2,后续media永远是2,误差始终是1>0.1,就进入死循环了。 - 第二个问题:
raiz_exata声明为返回float类型,但仅在误差刚好为0的分支有return语句,循环正常结束后没有return返回计算得到的media,会返回不可预期的垃圾值。 - 第三个问题:
main函数中调用raiz_exata后没有接收返回值,也没有打印最终计算结果,用户看不到输出的平方根值。 - 可选优化点:浮点数直接判断
erro == 0可靠性很低,浮点数计算存在精度误差,几乎不会出现刚好等于0的情况,可以直接删掉这个分支,统一交给while循环的误差判断逻辑处理即可。
修复后可正常运行的代码
#include <stdio.h> int raiz_inteira(int valor) { int impar = 1, cont = 0; while(valor >= impar) { valor = valor - impar; cont ++; impar+=2; } return cont; } // 把base和teto参数改为float类型,避免整数截断 float raiz_exata(float valor, float base, float teto) { float media = (base+teto)/2.0; float erro = media*media-valor; if(erro < 0) { erro *= -1; } while(erro > 0.1) { if(media*media > valor) { teto = media; } else { base = media; } media = (base+teto)/2.0; erro = media*media-valor; if(erro < 0) { erro *= -1; } } // 循环结束后返回计算结果 return media; } int main() { int teto, base, entrada; float resultado; printf("Type a number:\n"); scanf("%d",&entrada); base = raiz_inteira(entrada); teto = base+1; resultado = raiz_exata(entrada,base,teto); printf("计算得到的平方根为:%f\n", resultado); return 0; }
内容的提问来源于stack exchange,提问作者Magno Leal
相关产品推荐
相关产品推荐

