omohayui blog

おも‐はゆ・い【面映ゆい】[形][文]おもはゆ・し[ク]《顔を合わせるとまばゆく感じられる意》きまりが悪い。てれくさい。

Exercise on A Tour of Go

A Tour of Go の練習問題 『Loops and Functions』 についてのメモ

ニュートン法の式

文系(美術系)の自分にはそもそも計算式の意味が・・・

10回ループ

問題文に書いてある通り、とりあえず ニュートン法の式をそのまま関数に入れて 10回ループさせて x の値を増やしていき math.Sqrt との近似値を確認する。

package main

import (
    "fmt"
    "math"
)

func Sqrt(x float64) float64 {
    z := float64(1)
    for i := 0; i < 10; i++ {
        z = z - (z * z - x) / 2 * z
    }
    return z
}

func main() {
    x  := float64(2)
    sq := Sqrt(x)
    ms := math.Sqrt(x)
    fmt.Println(ms, sq)
    // Diff
    fmt.Println(ms - sq)
}

10回ループした結果

1.4142135623730951 1.3351578377717581
0.07905572460133703

10000回ループした結果

1.4142135623730951 1.4106685607006662
0.0035450016724289934

ここまではなんとか・・・ 10000回ループすると math.Sqrt に近づいているのがわかる

zの値の直前との差が小さくなったら停止するようにループを変更

if 文を追加して直前のzの値との差が定義した許容値以下になったら break するように修正

package main

import (
    "fmt"
    "math"
)

const tolerance = 0.001

func Sqrt(x float64) float64 {
    z := float64(1)
    t := z
    for {
        z = z - (z * z - x) / 2 * z
        if math.Abs(z - t) < tolerance {
            break
        }
        t = z
    }
    return z
}

func main() {
    x  := float64(2)
    sq := Sqrt(x)
    ms := math.Sqrt(x)
    fmt.Println(ms, sq)
    // Diff
    fmt.Println(ms - sq)
}

結果

1.4142135623730951 1.414713296482291
-0.000499734109195904

最初、自分は直前との差を出すのに if z - t < tolerance { とやっていてうまくいかず・・・

調べたら差分がマイナスになることもあるので絶対値をもとめる math.Abs を使うべしということがわかった

がしかしチュートリアル充実してるし
思ってたよりGoシンプルでわかりやすいし
逃げずにコツコツ勉強しようと思います。たぶん。