Golang牛顿法实现疑问:首次迭代后z²为何恒大于x?
牛顿法求平方根首次迭代后z²≥x的原因及验证
首先明确前提:我们讨论的是x>0(求平方根的合理输入)、z≠0(否则会触发除零错误)的情况,且默认关注正平方根(若初始z为负,迭代后会转为正,推导逻辑一致)。
首次迭代的数学推导
代码中首次迭代的公式是:
z -= ((z*z - x) / (2*z))
将其化简为数学表达式,设初始值为z₀,首次迭代后得到z₁:
$$
z_1 = z_0 - \frac{z_0^2 - x}{2z_0} = \frac{z_0^2 + x}{2z_0}
$$
现在计算z₁²与x的差值:
$$
z_1^2 - x = \left( \frac{z_0^2 + x}{2z_0} \right)^2 - x = \frac{(z_0^2 - x)2}{4z_02}
$$
由于平方数非负,分母$4z_02$始终为正(z₀≠0),因此$z_12 - x \geq 0$,即z₁²≥x:
- 当且仅当初始z₀恰好等于√x时,$z_0^2 - x=0$,此时z₁²=x;
- 其他所有情况,z₁²必然大于x。
这就解释了为何首次迭代后z²总是大于等于x,你测试未找到反例是因为数学上不存在这样的反例。
关于返回错误根的担忧
代码中的for循环会在z²>x时持续迭代,每次迭代的公式同样是牛顿法的步骤:
$$
z_{n+1} = \frac{z_n^2 + x}{2z_n}
$$
由于首次迭代后z₁≥√x,后续迭代会让z逐渐向√x收敛(每次迭代的z都会小于前一次的z,同时始终大于等于√x),直到z²≤x时退出循环。此时的z已经是√x的足够近似值,不会返回错误根。
原代码展示
package main import ( "fmt" ) func Sqrt(x, z float64) float64 { z -= ((z*z - x) / (2*z)) for z*z > x { z -= ((z*z - x) / (2*z)) } return z } func main() { fmt.Println(Sqrt(100, 1)) }
内容的提问来源于stack exchange,提问作者Vishak Arudhra
相关产品推荐
相关产品推荐

