有没有一个简单的方法可以计算大数的平方根?

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

Is there a simple method for square root of big.Rat?

问题

我需要找到一个大数的平方根。有没有一种方法可以在不丢失(已经存在的)精度的情况下进行计算?

例如,我可以将分子和分母转换为浮点数,获取平方根,然后再转换回来...

func ratSquareRoot(num *big.Rat) *big.Rat {
    f, exact := num.Float64() //Yuck! Floats!
    squareRoot := math.Sqrt(f)
    var accuracy int64 = 10 ^ 15 //float64的有效数字位数
    return big.NewRat(int64(squareRoot*float64(accuracy)), accuracy) 
    // ^ 这样做完全没有意义。而且可能没有很好地简化。
}

...但这样会消除使用有理数的所有精度。有没有更好的方法来做这个?

英文:

I need to find the square root of a big.Rat. Is there a way to do it without losing (already existing) accuracy?

For example, I could convert the numerator and denominator into floats, get the square root, and then convert it back...

func ratSquareRoot(num *big.Rat) *big.Rat {
    f, exact := num.Float64() //Yuck! Floats!
    squareRoot := math.Sqrt(f)
    var accuracy int64 = 10 ^ 15 //Significant digits of precision for float64
    return big.NewRat(int64(squareRoot*float64(accuracy)), accuracy) 
    // ^ This is now totally worthless. And also probably not simplified very well.

}

...but that would eliminate all of the accuracy of using a rational. Is there a better way of doing this?

答案1

得分: 2

big.Float类型具有.Sqrt(x)操作,并且可以明确定义所需的精度。我建议尝试使用它,并使用你问题中的相同操作将结果转换回Rat,只需操作big.Int值。

	r := big.NewRat(1, 3)

	var x big.Float
	x.SetPrec(30) // 我没有正确理解'Prec'部分,比我更仔细地阅读文档并进行实验
	x.SetRat(r)

	var s big.Float
	s.SetPrec(15)
	s.Sqrt(&x)

	r, _ = s.Rat(nil)
	fmt.Println(x.String(), s.String())
	fmt.Println(r.String(), float64(18919)/float64(32768))

playground

英文:

The big.Float type has a .Sqrt(x) operation, and handles defining explicitly the precision you aim for. I'd try to use that and convert the result back to a Rat with the same operations in your question, only manipulating big.Int values.

	r := big.NewRat(1, 3)

	var x big.Float
	x.SetPrec(30) // I didn't figure out the 'Prec' part correctly, read the docs more carefully than I did and experiement
	x.SetRat(r)

	var s big.Float
	s.SetPrec(15)
	s.Sqrt(&x)

	r, _ = s.Rat(nil)
	fmt.Println(x.String(), s.String())
	fmt.Println(r.String(), float64(18919)/float64(32768))

playground

huangapple
  • 本文由 发表于 2022年1月16日 01:00:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/70723547.html
匿名

发表评论

匿名网友

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

确定