Golang中小数平方根的任意精度 [英] Arbitrary precision for decimals square roots in golang

查看:264
本文介绍了Golang中小数平方根的任意精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种以任意精度(例如点后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的力量后,我浏览了文档,但是找不到类似的东西.

After seeing the power of math/big I skimmed through the documentation but have not found anything similar.

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

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)是:

And using it, one can find that square(8537341, 50) is:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆