Julia 中的任意精度算术
Arbitrary Precision Arithmetic in Julia
有人问过这个问题,但不是这样问的。我有一个 Python 小程序,可以找到 n (1 <= n <= 10000) 的平方根的连分数。
我一直在尝试在 Julia 中执行此操作,但我不知道该怎么做。主要是因为它处理无理数(如果 x 不是完全平方,则 sqrt(x) 是无理数,例如 sqrt(2) = 1.414213...)。所以我认为我不能使用有理数 class.
这里说 https://docs.julialang.org/en/latest/manual/integers-and-floating-point-numbers/#Arbitrary-Precision-Arithmetic-1 Julia 可以使用 BigFloats 进行任意精度的运算。但他们似乎不够准确。
我也曾尝试在 Python(来自 Julia)中使用 PyCall 和 Decimals 包,但出现了奇怪的错误(如果它们有帮助,我可以 post)。
这是我的 Python 有效的程序。我的问题是如何在 Julia 中执行此操作?
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
如您所见,我需要一种计算精确平方根的方法,以及一种获取数字整数部分的方法。这就是全部,除了很多很多的精度!
伙计们,我没有 post 我的 Julia 代码,因为我不想有一个小手稿来回答!但在这里,它有效。正如我在下面的评论中所说,我使用 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解决了,非常感谢。
就像 Python 的 decimal.Decimal 一样,您可以配置 Julia 的 BigFloat 的精度:
setprecision(however_many_bits)
请注意,这是以位为单位,与 decimal.Decimal 不同,因为 BigFloat 不使用小数。
user2357112的回答是问题的核心,也是本题的正确答案。
然而,为了完成,"how would I get this python script to run in julia" 的 'literal' 问题本身就是一个有趣的问题,因为它并不像最初看起来那么简单,因为 this issue, 所以我也会展示如何做到这一点。
假设您在当前目录中有名为 "testo.py" 的 python 脚本(并且具有正确的 import decimal
语句等),那么下面是如何将其作为 python模块和运行相关函数:
using PyCall
unshift!(PyVector(pyimport("sys")["path"]), ""); # as per https://github.com/JuliaPy/PyCall.jl#troubleshooting
testo = pyimport("testo");
testo[:oddPeriodSquareRoots]() # will output '1322'
有人问过这个问题,但不是这样问的。我有一个 Python 小程序,可以找到 n (1 <= n <= 10000) 的平方根的连分数。
我一直在尝试在 Julia 中执行此操作,但我不知道该怎么做。主要是因为它处理无理数(如果 x 不是完全平方,则 sqrt(x) 是无理数,例如 sqrt(2) = 1.414213...)。所以我认为我不能使用有理数 class.
这里说 https://docs.julialang.org/en/latest/manual/integers-and-floating-point-numbers/#Arbitrary-Precision-Arithmetic-1 Julia 可以使用 BigFloats 进行任意精度的运算。但他们似乎不够准确。
我也曾尝试在 Python(来自 Julia)中使用 PyCall 和 Decimals 包,但出现了奇怪的错误(如果它们有帮助,我可以 post)。
这是我的 Python 有效的程序。我的问题是如何在 Julia 中执行此操作?
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
如您所见,我需要一种计算精确平方根的方法,以及一种获取数字整数部分的方法。这就是全部,除了很多很多的精度!
伙计们,我没有 post 我的 Julia 代码,因为我不想有一个小手稿来回答!但在这里,它有效。正如我在下面的评论中所说,我使用 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解决了,非常感谢。
就像 Python 的 decimal.Decimal 一样,您可以配置 Julia 的 BigFloat 的精度:
setprecision(however_many_bits)
请注意,这是以位为单位,与 decimal.Decimal 不同,因为 BigFloat 不使用小数。
user2357112的回答是问题的核心,也是本题的正确答案。
然而,为了完成,"how would I get this python script to run in julia" 的 'literal' 问题本身就是一个有趣的问题,因为它并不像最初看起来那么简单,因为 this issue, 所以我也会展示如何做到这一点。
假设您在当前目录中有名为 "testo.py" 的 python 脚本(并且具有正确的 import decimal
语句等),那么下面是如何将其作为 python模块和运行相关函数:
using PyCall
unshift!(PyVector(pyimport("sys")["path"]), ""); # as per https://github.com/JuliaPy/PyCall.jl#troubleshooting
testo = pyimport("testo");
testo[:oddPeriodSquareRoots]() # will output '1322'