0

there is no error in the following code.

package main

import (
    "fmt"
    "math"
)

type ErrNegativeSqrt float64

func (e ErrNegativeSqrt) Error() string {
    return fmt.Sprintf("cannot Sqrt negative number: %v", float64(e))
}

func Sqrt(x float64) (float64, error) {
    if x < 0 {
        err := ErrNegativeSqrt(x)
        return x, err
    }
    z := x
    var delta = 1e-10
    for {
        n := z - (z*z - x) / (2*z)
        if math.Abs(n - z) < delta {
            break
        }
        z = n
    }
    return z, nil
}

func main() {
    fmt.Println(Sqrt(2))
    fmt.Println(Sqrt(-3))
}

But when I change the for loop in func Sqrt(), it led to infinite loop?

func Sqrt(x float64) (float64, error) {
    if x < 0 {
        err := ErrNegativeSqrt(x)
        return x, err
    }
    z := x
    var delta = 1e-10
    for {
        n := z - (z*z - x) / (2*z)
        if math.Abs(n - z) < delta {
            z = n // here ....
            break // break here
        }
    }
    return z, nil
}

Why there are different?

2
  • Are you sure? On which input? Playground? Commented Aug 23, 2016 at 10:08
  • @Volker, both on the playground and on my laptop, the playground return process took too long Commented Aug 23, 2016 at 10:14

1 Answer 1

4

The second loop will be infinite since the logic is flawed. In this code:

for {
    n := z - (z*z - x) / (2*z)
    if math.Abs(n - z) < delta {
        z = n // here ....
        break // break here
    }
}

value of z never updates to the newly calculated value. This results in n := z - (z*z - x) / (2*z) always working on the same z, that is equal to x, since the condition math.Abs(n - z) < delta never gets to be true.

You need to assign to z again so it gets updated. You can check this by logging value of z in the loop. Example code: https://play.golang.org/p/9H7Uze4gip

Sign up to request clarification or add additional context in comments.

2 Comments

thanks, the error is hard to detect for a newbie of Go.
I don't see how this is related to Go, the problem is that you never update the value of z, which is an algorithmical error. If you pull out the z=n from the loop it works just fine (or duplicate, to keep the latest iteration).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.