package main import ( "fmt" "math" "os" "strconv" ) const usage = "usage: sqrt " const min_threshold = 1e-200 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.4g %0.2d %0.20f %0.20f %0.4g\n", threshold, iterations, right_answer, answer, right_answer-answer) threshold = threshold / 10.0 } }