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

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

go, for loop and break, infinite loop

问题

以下是代码的翻译:

以下代码没有错误

package main

import (
	"fmt"
	"math"
)

type ErrNegativeSqrt float64

func (e ErrNegativeSqrt) Error() string {
    return fmt.Sprintf("无法对负数进行平方根操作: %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))
}

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

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 // 这里......
			break // 在这里中断循环
		}
	}
	return z, nil
}

为什么会有不同的结果?

英文:

there is no error in the following code.

package main

import (
	&quot;fmt&quot;
	&quot;math&quot;
)

type ErrNegativeSqrt float64

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

func Sqrt(x float64) (float64, error) {
	if x &lt; 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) &lt; 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 &lt; 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) &lt; delta {
            z = n // here ....
			break // break here
		}
	}
	return z, nil
}

Why there are different?

答案1

得分: 4

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

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

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:

for {
    n := z - (z*z - x) / (2*z)
    if math.Abs(n - z) &lt; 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) &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:

确定