首先,你算法不正確。其計算公式爲:

您與建模這樣的:
z - (z*z - x)/2*z
但它應該是:
z - (z*z - x)/2/z
或者
z - (z*z - x)/(2*z)
(您不正確公式必須運行50萬次迭代,甚至可以達到0.001
!正確的公式使用像4次迭代,以獲得儘可能接近1e-6
在x = 2
情況。)
接下來,z=1
初始值是不是最好的一個隨機數(它可能工作以及爲少數像2
)。您可以使用z = x/2
開始,這是一個非常簡單的初始值,並使您以更少的步驟更接近結果。
更多選項不必然使其更具可讀性或優雅,這是主觀的:
可以命名結果z
所以return語句可以是「裸」。你也可以創建一個循環變量來計算迭代次數,如果你將當前的「退出」條件移動到循環中,如果符合,你可以打印迭代次數並且可以簡單地返回。您還可以將計算到if
的初始化部分:
func Sqrt(x float64) (z float64) {
z = x/2
for i, old := 1, 0.0; ; i++ {
if old, z = z, z-(z*z-x)/2/z; math.Abs(old-z) < 1e-5 {
fmt.Printf("Ran %v iterations\n", i)
return
}
}
}
您也可以移動z = x/2
到for
的初始化部分,但是,你不能有一個名爲結果(z
別的地方變種將創建這將影子命名的返回值):
func Sqrt(x float64) float64 {
for i, z, old := 1, x/2, 0.0; ; i++ {
if old, z = z, z-(z*z-x)/2/z; math.Abs(old-z) < 1e-5 {
fmt.Printf("Ran %v iterations\n", i)
return z
}
}
}
注:我開始迭代計數器與1
,因爲「退出」狀態在我的情況是內for
,並不是for
的條件。
Yipes!感謝您回答我應該問的問題(我的算法是否正確?)以及我問的問題。 –