Julia中的任意精度算法

时间:2017-08-20 02:41:28

标签: python julia square-root arbitrary-precision continued-fractions

这有点被问到,但不是这样。我有一个小的Python程序,它找到n的平方根的连续分数(1 <= n <= 10000)。

我一直试图在朱莉娅这样做,我不知道如何。主要是因为它处理无理数(如果x不是一个完美的正方形,则sqrt(x)是不合理的,例如sqrt(2)= 1.414213 ...)。所以我不认为我可以使用理性课。

这里说https://docs.julialang.org/en/release-0.4/manual/integers-and-floating-point-numbers/#man-arbitrary-precision-arithmetic Julia可以使用BigFloats进行任意精度算术。但它们似乎不够准确。

我也尝试在Python中使用PyCall和Decimals包(来自Julia),但是会出现奇怪的错误(如果它们有用,我可以发布它们)。

这是我的Python程序。我的问题是如何在朱莉娅这样做?

def continuedFractionSquareRoots():
''' 
  For each number up to 100, get the length of the continued fraction 
  of the square root for it.
'''

decimal.getcontext().prec = 210 # Need lots of precision for this problem.

continuedFractionLengths = []
for i in range(1, 101):

    # For perfect squares, the period is 0
    irrationalNumber = decimal.Decimal(i).sqrt()
    if irrationalNumber == int(irrationalNumber):
        continue        

    continuedFractionLength = 0
    while True:

        intPart = irrationalNumber.to_integral_exact(rounding=decimal.ROUND_FLOOR)
        if continuedFractionLength == 0:
            firstContinuedFractionTimes2 = int(intPart*2)

        continuedFractionLength += 1
        if intPart == firstContinuedFractionTimes2:
            # Have reached the 'period' end for this fraction
            break

        fractionalPart = irrationalNumber - intPart
        irrationalNumber = 1 / fractionalPart

continuedFractionLengths.append(continuedFractionLength)
return continuedFractionLengths

正如您所看到的,我需要一种计算精确平方根的方法,以及获取数字的整数部分的方法。除了很多精确度之外,这一切都非常真实!

伙计们,我没有发布我的朱莉娅代码,因为我不想要一个小手稿来回答!但它在这里是有效的。正如我在下面的评论中所说,我使用setprecision函数将精度设置为高值并且它可以正常工作。我凭经验获得了711的价值。

setprecision(711)

function continuedFractionSquareRoots()
#=
  For each number up to 100, get the length of the continued fraction 
  of the square root for it.
=#

continuedFractionLengths = Int[]
for i=1:100

    # For perfect squares, the period is 0
    irrationalNumber = BigFloat(sqrt(BigFloat(i)))
    if irrationalNumber == floor(irrationalNumber)
        continue
    end

    continuedFractionLength = 0
    while true

        intPart = floor(irrationalNumber)
        if continuedFractionLength == 0
            firstContinuedFractionTimes2 = intPart*2
        end

        continuedFractionLength += 1
        if intPart == firstContinuedFractionTimes2
            # Have reached the 'period' end for this fraction
            break
        end

        fractionalPart = irrationalNumber - intPart
        irrationalNumber = BigFloat(1) / fractionalPart

    end

    push!(continuedFractionLengths, continuedFractionLength)

end


return continuedFractionLengths
end

所以无论如何,user2357112解决了它,非常感谢。

2 个答案:

答案 0 :(得分:2)

就像Python的decimal.Decimal一样,你可以配置Julia的BigFloat的精度:

setprecision(however_many_bits)

请注意,这是以位为单位,与decimal.Decimal不同,因为BigFloat不使用小数。

答案 1 :(得分:1)

user2357112的答案是问题的核心,也是这个问题的正确答案。

然而,为了完成,“我将如何让这个python脚本在julia中运行”这个“文字”问题本身就是一个有趣的问题,因为它并不像它看起来那么简单。 this issue,所以我也将展示如何做到这一点。

假设您的当前目录中有一个名为“testo.py”的python脚本(以及正确的import decimal语句等),那么这里是如何将其作为python模块导入并运行相关函数: / p>

using PyCall
unshift!(PyVector(pyimport("sys")["path"]), ""); # as per https://github.com/JuliaPy/PyCall.jl#troubleshooting
testo = pyimport("testo");
testo[:oddPeriodSquareRoots]()  # will output '1322'