你如何在 Julia 中进行任意精度计算?

How do you do arbitrary precision calculations in Julia?

我来自 Python 背景,使用 Python 的 Decimal 模块进行任意精度计算的一个重要点是知道什么时候需要指定 Decimal 类型的数字,例如,概率计算。

您必须多久在 Julia 计算中为数字指定任意精度类型?

我通过例子学得最好,我想解决的例子如下。

计算在不放回的情况下随机抽取一桶 26 个 ABC 到 Z 块 26!、3(26)! 和 5(26)! 时至少一次成功的概率。次。

给定:

一次试验成功 = 以正确的顺序随机抽出方块:A、B、C 到 Z。

随机试验次数为n = 26!或 3n 或 5n。

一次随机试验的成功概率,p = 1/n

一次随机试验的失败概率是 f = 1 – p。

计算(根据需要尽可能少地使用类型规范):

使用 CL = 1 – f^n

的 n 次试验中至少一次成功的置信水平 CL

使用 CL = 1 - f^(3n) 进行 3n 次试验的 CL

使用 CL = 1 - f^(5n) 进行 5n 次试验的 CL

Julia 在计算 "big" 数字类型规范方面做得很好。 例如,在下面的代码中我只指定一个数字为 big"26",其他都是自动的。

我刚开始使用 Julia,但多年来一直以各种方式进行任意精度计算。毫无疑问,Julia 提供了我所拥有过的最愉快的体验。

# Set precision to 150 bits which should be adequate precision.
setprecision(150)

# Note that we only have to specify a "big" number here.
n = factorial(big"26")
println("n = factorial(big\"26\") = ", n)
println("Note that we never have to use \"big\" again in the following code.")
println("typeof(n) = ", typeof(n), "\n")  

# p is the probability of success on 1 trial.
p = 1/n
println("p = 1/n = ", p)
# Note we did not have to specify the type of p.
println("typeof(p) = ", typeof(p), "\n")

# f is the probability of failure on 1 trial.
f = 1 - p
println("f = 1 - p = ", f)
println("typeof(f) = ", typeof(f), "\n")   

# CL is the probability of at least 1 success in n trials.
# CL stands for confidence level.   
CL = 1 - f^n
println("The 63% CL for n trials = 1 - f^n = ", CL)
println("typeof(CL) = ", typeof(CL), "\n")   

# Here is the 95% conf. level using 3n random trials.
CL95 = 1 - f^(3n)
println("The 95% CL for 3n trials = ", CL95)
println("typeof(CL95) = ", typeof(CL95), "\n")

# Here is the 99% conf. level using 5n random trials.
CL99 = 1 - f^(5n)
println("The 99% CL for 5n trials = ", CL99)
println("typeof(CL99) = ", typeof(CL99), "\n")

""" ============================= Output ==============================
n = factorial(big"26") = 403291461126605635584000000
Note that we never have to use "big" again in the following code.
typeof(n) = BigInt

p = 1/n = 2.4795962632247974600749435458479566174226555415e-27
typeof(p) = BigFloat

f = 1 - p = 9.9999999999999999999999999752040373677520254001e-01
typeof(f) = BigFloat

The 63% CL for n trials = 1 - f^n = 6.3212055882855767839219205578358958187929158048e-01
typeof(CL) = BigFloat

The 95% CL for 3n trials = 9.5021293163213605701567013782477488392169554992e-01
typeof(CL95) = BigFloat

The 99% CL for 5n trials = 9.9326205300091453290223898909666750856240017783e-01
typeof(CL99) = BigFloat
"""

如果你想要像Python中的Decimal那样的精度十进制浮点数,我自己写了一个。您可以将小数精度设置为任何正整数值。如果您需要该模块的副本,请与我联系。

julia> factorial(BigInt(26))
403291461126605635584000000

julia> println("How many decimal digits do we need?")
How many decimal digits do we need?

julia> length(string(  factorial(BigInt(26))  ))
27

julia> using PDFPs

julia> PDFP_setDefaultPrecision(40)
40

julia> n = PDFP(    factorial(BigInt(26))    )
PDFP(0, 26, [4, 0, 3, 2, 9, 1, 4, 6, 1, 1, 2, 6, 6, 0, 5, 6, 3, 5, 5, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

julia> disp(a::PDFP) = println(PDFP_toShortCommonString(a))
disp (generic function with 1 method)

julia> p = 1/n
PDFP(0, -27, [2, 4, 7, 9, 5, 9, 6, 2, 6, 3, 2, 2, 4, 7, 9, 7, 4, 6, 0, 0, 7, 4, 9, 4, 3, 5, 4, 5, 8, 4, 7, 9, 5, 6, 6, 1, 7, 4, 2, 2])

julia> disp(p)
2.47960E-27

julia> println("Let's call failure q as per convention in probability questions")
Let's call failure q as per normal in probability questions

julia> q = 1 - p
PDFP(0, -1, [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 5, 2, 0, 4, 0, 3, 7, 3, 6, 7, 7, 5, 2])

julia> disp(q)
1.00000

julia> PDFP_toFortranString(q)
"9.999999999999999999999999975204037367752E-1"

julia> at_least_one_success_in_n_trials = 1 - q^n
PDFP(0, -1, [6, 3, 2, 1, 2, 0, 5, 5, 8, 8, 2, 8, 5, 5, 8, 0, 5, 5, 6, 0, 2, 0, 5, 7, 9, 5, 3, 4, 5, 6, 9, 0, 2, 1, 9, 8, 7, 6, 4, 9])

julia> disp(at_least_one_success_in_n_trials)
0.632121

julia> at_least_one_success_in_3n_trials = 1 - q^(3*n)
PDFP(0, -1, [9, 5, 0, 2, 1, 2, 9, 3, 1, 6, 3, 2, 1, 3, 6, 2, 1, 0, 1, 6, 5, 3, 1, 1, 5, 3, 8, 4, 6, 6, 4, 3, 9, 0, 4, 8, 2, 9, 1, 0])

julia> disp(at_least_one_success_in_3n_trials)
0.950213

julia> at_least_one_success_in_5n_trials = 1 - q^(5*n)
PDFP(0, -1, [9, 9, 3, 2, 6, 2, 0, 5, 3, 0, 0, 0, 9, 1, 4, 5, 6, 7, 4, 4, 6, 4, 3, 7, 4, 3, 4, 3, 4, 4, 7, 4, 8, 6, 8, 9, 6, 2, 8, 1])

julia> disp(at_least_one_success_in_5n_trials)
0.993262

您可以使用 setprecision(n),其中 n 是您想要的精度。

然后,使用BigFloat定义变量。

最后,using Printf显示数字。

请参阅以下屏幕截图中的示例。