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

59 lines
1.0 KiB
Go
Raw Permalink Normal View History

2012-08-02 13:39:21 -07:00
package main
import (
"fmt"
"math"
2012-08-28 20:35:32 -07:00
"os"
"strconv"
2012-08-02 13:39:21 -07:00
)
2012-08-28 20:35:32 -07:00
const usage = "usage: sqrt <number>"
2012-08-31 12:30:10 -07:00
const min_threshold = 1e-16
2012-08-02 13:39:21 -07:00
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
}
2012-08-02 13:39:21 -07:00
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() {
2012-08-28 20:35:32 -07:00
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)
}
2012-08-02 13:39:21 -07:00
threshold := 1.0
2012-08-28 20:35:32 -07:00
right_answer := math.Sqrt(i)
2012-08-02 13:39:21 -07:00
for threshold > min_threshold {
2012-08-28 20:35:32 -07:00
answer, iterations, err := Sqrt(i, threshold)
if err != nil {
panic(err)
}
2012-08-31 12:30:10 -07:00
fmt.Printf("%0.4E %0.4d %0.20f %0.20f %0.4e\n",
2012-08-28 20:35:32 -07:00
threshold, iterations, right_answer, answer,
right_answer-answer)
2012-08-02 13:39:21 -07:00
threshold = threshold / 10.0
}
}