问题描述

我正在寻找一种以任意精度(例如点后50位数左右)计算平方根的方法.

I am looking for a way to calculate a square root with an arbitrary precision (something like 50 digits after the dot).

在python中,可以通过十进制轻松访问它:

In python, it is easily accessible with Decimal:

from decimal import *
getcontext().prec = 50
Decimal(2).sqrt() # and here you go my 50 digits
math/big
math/big

我唯一的选择是编写某种数值计算方法,该方法将反复尝试计算答案?

So is my only option is to write some sort of numerical computing method which will iteratively try to compute the answer?

推荐答案

这是我自己的平方根计算实现.在等待答案时,我决定尝试计算平方根的方法.它有很多方法,但最终我找到了通过减法求平方根 pdf,我真的很喜欢它,因为该算法的描述只有几行(与牛顿法相比,我之前从未见过).

This is my own implementation of square root calculation. While waiting for answers, I decided to give methods of computing square roots a try. It has a whole bunch of methods but at the very end I found a link to a Square roots by subtraction pdf, which I really liked because the description of the algorithm is only a couple of lines (and I have not seen it before in comparison to Newton's method).

这是我的实现(bigint不能很好地配合使用):

So here is my implementation (bigint is not really nice to work with in go):

func square(n int64, precision int64) string{
    ans_int := strconv.Itoa(int(math.Sqrt(float64(n))))

    limit   := new(big.Int).Exp(big.NewInt(10), big.NewInt(precision + 1), nil)
    a       := big.NewInt(5 * n)
    b       := big.NewInt(5)
    five    := big.NewInt(5)
    ten     := big.NewInt(10)
    hundred := big.NewInt(100)

    for b.Cmp(limit) < 0{
        if a.Cmp(b) < 0{
                a.Mul(a, hundred)
            tmp := new(big.Int).Div(b, ten)
            tmp.Mul(tmp, hundred)
            b.Add(tmp, five)
        } else {
            a.Sub(a, b)
            b.Add(b, ten)
        }
    }
    b.Div(b, hundred)

    ans_dec := b.String()

    return ans_dec[:len(ans_int)] + "." + ans_dec[len(ans_int):]
}

PS .感谢Nick Craig-Wood用您令人赞叹的注释改进了代码.

P.S. thank you Nick Craig-Wood for making the code better with your amazing comment.

square(8537341, 50)
square(8537341, 50)

2921.8728582879851242173838229735693053765773170487

2921.8728582879851242173838229735693053765773170487

仅是python的最后一位

which is only by one last digit of from python's

getcontext().prec = 50
print str(Decimal(8537341).sqrt())

2921.8728582879851242173838229735693053765773170488

2921.8728582879851242173838229735693053765773170488

此数字不可用,因为最后一位数字不是很精确.

This one digit is off because the last digit is not really precise.

一如既往.

As always Go Playground.

P.S..如果有人会找到本机的方法,我很乐意接受并支持.

P.S. if someone would find a native way to do this, I would gladly give my accept and upvote.

这篇关于Golang中小数平方根的任意精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!