1
0
Fork 0
gotour-notes/exercises/00-sqrt/go.go

59 lines
1.0 KiB
Go

package main
import (
"fmt"
"math"
"os"
"strconv"
)
const usage = "usage: sqrt <number>"
const min_threshold = 1e-16
type ErrNegativeSqrt float64
func (e ErrNegativeSqrt) Error() string {
return fmt.Sprintf("cannot Sqrt negative number: %v", float64(e))
}
func Sqrt(x float64, threshold float64) (z float64, iterations int, err error) {
if x < 0 {
err = ErrNegativeSqrt(x)
return
}
z = x
old_z := z
for {
z = z - (z*z-x)/(2*x)
if math.Abs(z-old_z) < threshold {
break
}
old_z = z
iterations++
}
return
}
func main() {
if len(os.Args) != 2 {
fmt.Fprintf(os.Stderr, "%v\n", usage)
os.Exit(1)
}
i, err := strconv.ParseFloat(os.Args[1], 32)
if err != nil {
panic(err)
}
threshold := 1.0
right_answer := math.Sqrt(i)
for threshold > min_threshold {
answer, iterations, err := Sqrt(i, threshold)
if err != nil {
panic(err)
}
fmt.Printf("%0.4E %0.4d %0.20f %0.20f %0.4e\n",
threshold, iterations, right_answer, answer,
right_answer-answer)
threshold = threshold / 10.0
}
}