go,for循环和break,无限循环

huangapple go评论131阅读模式
英文:

go, for loop and break, infinite loop

问题

以下是代码的翻译:

  1. 以下代码没有错误
  2. package main
  3. import (
  4. "fmt"
  5. "math"
  6. )
  7. type ErrNegativeSqrt float64
  8. func (e ErrNegativeSqrt) Error() string {
  9. return fmt.Sprintf("无法对负数进行平方根操作: %v", float64(e))
  10. }
  11. func Sqrt(x float64) (float64, error) {
  12. if x < 0 {
  13. err := ErrNegativeSqrt(x)
  14. return x, err
  15. }
  16. z := x
  17. var delta = 1e-10
  18. for {
  19. n := z - (z*z - x) / (2*z)
  20. if math.Abs(n - z) < delta {
  21. break
  22. }
  23. z = n
  24. }
  25. return z, nil
  26. }
  27. func main() {
  28. fmt.Println(Sqrt(2))
  29. fmt.Println(Sqrt(-3))
  30. }

但是,当我在func Sqrt()中更改了for循环时,它导致了无限循环。

  1. func Sqrt(x float64) (float64, error) {
  2. if x < 0 {
  3. err := ErrNegativeSqrt(x)
  4. return x, err
  5. }
  6. z := x
  7. var delta = 1e-10
  8. for {
  9. n := z - (z*z - x) / (2*z)
  10. if math.Abs(n - z) < delta {
  11. z = n // 这里......
  12. break // 在这里中断循环
  13. }
  14. }
  15. return z, nil
  16. }

为什么会有不同的结果?

英文:

there is no error in the following code.

  1. package main
  2. import (
  3. &quot;fmt&quot;
  4. &quot;math&quot;
  5. )
  6. type ErrNegativeSqrt float64
  7. func (e ErrNegativeSqrt) Error() string {
  8. return fmt.Sprintf(&quot;cannot Sqrt negative number: %v&quot;, float64(e))
  9. }
  10. func Sqrt(x float64) (float64, error) {
  11. if x &lt; 0 {
  12. err := ErrNegativeSqrt(x)
  13. return x, err
  14. }
  15. z := x
  16. var delta = 1e-10
  17. for {
  18. n := z - (z*z - x) / (2*z)
  19. if math.Abs(n - z) &lt; delta {
  20. break
  21. }
  22. z = n
  23. }
  24. return z, nil
  25. }
  26. func main() {
  27. fmt.Println(Sqrt(2))
  28. fmt.Println(Sqrt(-3))
  29. }

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

  1. func Sqrt(x float64) (float64, error) {
  2. if x &lt; 0 {
  3. err := ErrNegativeSqrt(x)
  4. return x, err
  5. }
  6. z := x
  7. var delta = 1e-10
  8. for {
  9. n := z - (z*z - x) / (2*z)
  10. if math.Abs(n - z) &lt; delta {
  11. z = n // here ....
  12. break // break here
  13. }
  14. }
  15. return z, nil
  16. }

Why there are different?

答案1

得分: 4

第二个循环将是无限循环,因为逻辑有误。在这段代码中:

  1. for {
  2. n := z - (z*z - x) / (2*z)
  3. if math.Abs(n - z) < delta {
  4. z = n // 这里 ....
  5. break // 在这里跳出循环
  6. }
  7. }

z的值从未更新为新计算的值。这导致n := z - (z*z - x) / (2*z)始终在相同的z上工作,即等于x,因为条件math.Abs(n - z) < delta永远不会为真。

你需要再次给z赋值以便更新它。你可以通过在循环中记录z的值来进行检查。示例代码:https://play.golang.org/p/9H7Uze4gip

英文:

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

  1. for {
  2. n := z - (z*z - x) / (2*z)
  3. if math.Abs(n - z) &lt; delta {
  4. z = n // here ....
  5. break // break here
  6. }
  7. }

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) &lt; 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

huangapple
  • 本文由 发表于 2016年8月23日 18:04:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/39098142.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定