为了账号安全,请及时绑定邮箱和手机立即绑定

牛顿方法有更优雅的 Go 实现吗?

牛顿方法有更优雅的 Go 实现吗?

Go
拉风的咖菲猫 2021-09-27 21:17:51
我正在做 Go 教程,想知道是否有一种更优雅的方法来使用 Newton 的方法来计算平方根:练习:循环和函数,而不是这样:func Sqrt(x float64) float64 {    count := 0    var old_z, z float64 = 0, 1    for ; math.Abs(z-old_z) > .001; count++ {        old_z, z = z, z - (z*z - x) / 2*z    }    fmt.Printf("Ran %v iterations\n", count)    return z}(规范的一部分是提供迭代次数。)这里是完整的程序,包括包语句、导入和主要。
查看完整描述

2 回答

?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

首先,你的算法不正确。公式为:


//img1.sycdn.imooc.com//6151c49e000185e700960033.jpg

您对此进行了建模:


z - (z*z - x) / 2*z

但它应该是:


z - (z*z - x)/2/z

或者


z - (z*z - x)/(2*z)

(您不正确的公式不得不像半个百万次迭代甚至只得到尽可能接近运行0.001!正确的公式使用像4次迭代来获得尽可能接近1e-6的情况下x = 2)。


其次, 的初始值z=1对于随机数不是最好的(它可能适用于像 那样的小数2)。您可以使用z = x / 2一个非常简单的初始值开始,并以更少的步骤使您更接近结果。


其他选项不一定使它更具可读性或优雅,这是主观的:


您可以将结果命名为,z以便返回语句可以是“裸”的。如果您将当前的“退出”条件移动到循环中,您也可以创建一个循环变量来计算迭代次数,如果满足,则打印迭代次数并可以简单地返回。您还可以将计算移至 的初始化部分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。


查看完整回答
反对 回复 2021-09-27
?
杨魅力

TA贡献1811条经验 获得超6个赞

package main


import (

    "fmt"

    "math"

)


func Sqrt(x float64) float64 {

    z := 1.0

    // First guess

    z -= (z*z - x) / (2*z)

    // Iterate until change is very small

    for zNew, delta := z, z; delta > 0.00000001; z = zNew {

        zNew -= (zNew * zNew - x) / (2 * zNew)

        delta = z - zNew

    }

    return z

}


func main() {

    fmt.Println(Sqrt(2))

    fmt.Println(math.Sqrt(2))

}


查看完整回答
反对 回复 2021-09-27
  • 2 回答
  • 0 关注
  • 173 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信