Go语言中for循环条件调用函数为何失效?附示例解析
为什么Go语言中这个平方根计算的for循环版本不工作?
先看你给出的代码和运行输出:
package main import ( "fmt" "math" ) func Sqrt_working(x float64) float64 { var z float64 = 1.0 for { if math.Abs((z*z) - x) < 0.0001 { break } z -= ((z*z - x) / (2*z)) } return z } func Sqrt_not_working(x float64) float64 { var z float64 = 1.0 for math.Abs((z*z) - x) < 0.0001 { z -= ((z*z - x) / (2*z)) } return z } func main() { fmt.Println(Sqrt_working(2)) fmt.Println(Sqrt_not_working(2)) }
运行输出:
1.4142156862745099 1
核心原因:循环条件逻辑完全搞反了!
咱们拿x=2的初始场景拆解:z的初始值是1.0,此时z*z - x = 1 - 2 = -1,绝对值是1.0,这明显大于你设定的误差阈值0.0001。
- 对于正常工作的
Sqrt_working:它用无限for {}循环,内部判断逻辑是「如果误差足够小(小于0.0001),就退出循环」——因为初始误差很大,不会触发break,所以会正常执行迭代更新z,直到误差符合要求才退出,完美贴合牛顿法迭代求平方根的逻辑。 - 对于不工作的
Sqrt_not_working:它把判断条件写在了for循环的入口,意思变成了「只有当误差小于0.0001的时候,才会进入循环体执行迭代」。但初始状态误差远大于阈值,循环条件直接不成立,所以整个循环体一次都没执行,直接返回了初始值z=1.0。
修复方案
如果想把判断条件放在for循环入口,只需要把条件反过来,判断「当误差大于等于阈值时继续迭代」:
func Sqrt_fixed(x float64) float64 { var z float64 = 1.0 // 条件改为误差 >= 阈值时进入循环迭代 for math.Abs((z*z)-x) >= 0.0001 { z -= ((z*z - x) / (2*z)) } return z }
这样初始条件满足,循环会正常执行迭代,直到误差小于阈值时自动退出,结果就和正常版本一致了。
内容的提问来源于stack exchange,提问作者jrb
相关产品推荐
相关产品推荐

