在R语言中实现逐位平方根算法时遭遇死循环问题求助
排查R语言逐位平方根函数的无限循环问题
我来帮你分析下这个无限循环的原因,主要是你的代码把算法步骤的执行顺序搞混了,导致res的更新逻辑完全偏离了逐位求解的思路,进而让外层循环永远无法满足终止条件。
问题原因拆解
内层循环逻辑顺序错误
原伪代码的逻辑是:先找到最大的x,使得(res + x*d)² ≤ S,再更新res和缩小d的量级。但你的代码里每次x加1就立刻修改res和d,这导致d迅速变成极小值,res的更新也完全混乱,外层循环的(S - res*res) > eps条件永远无法被打破。外层循环未使用绝对值判断误差
当res²超过S时,S - res*res会变成负数,此时你的外层循环会直接停止,但实际上我们需要判断的是误差的绝对值是否小于等于eps,否则会出现提前终止或者误差过大的情况。内层循环的
x更新逻辑有误
你在内层循环里每次x+1就立刻更新res,这相当于每试一个x就直接把部分值加到res里,完全不符合“找到最大可行x后再一次性更新res”的逐位求解逻辑。
修正后的代码
sqrt.by.digit <- function(S, eps=1e-6) { res <- 0 d <- 1 # 先把d调整到合适的量级(找到比sqrt(S)小的最大10的幂次) while ((res + d)^2 <= S) { d <- d * 10 } d <- d / 10 while (abs(S - res * res) > eps) { x <- 0 # 找到最大的x,使得(res + x*d)^2 <= S while ((res + (x + 1)*d)^2 <= S) { x <- x + 1 } # 更新res为当前找到的最佳值 res <- res + x * d # 缩小d的量级,进入下一位的求解 d <- d / 10 } res } # 测试示例 print(sqrt.by.digit(10, 0.1))
代码解释
- 初始调整
d的量级:先把d放大到比平方根大的10的幂次,再缩小10倍,这样第一次求解的就是整数位,符合逐位从高位到低位求解的逻辑。 - 外层循环用绝对值判断误差:确保无论
res²是大于还是小于S,只要误差超过阈值就继续迭代。 - 内层循环正确寻找
x:先找到最大的x使得(res + x*d)^2 ≤ S,再一次性更新res,然后缩小d的量级,进入下一位(十分位、百分位等)的求解。
运行修正后的代码,sqrt.by.digit(10, 0.1)会输出3.16左右的结果,此时3.16²=9.9856,与10的误差是0.0144,小于设定的0.1,符合终止条件。
内容的提问来源于stack exchange,提问作者user9223383
相关产品推荐
相关产品推荐

