如何在julia中获得一个范围内的BigInt随机数



我需要在Julia中获得1和BigInt之间的随机数,但我无法在文档中找到如何做到这一点。下面的代码是我认为可行的:

julia> rand(BigInt(1):BigInt(2^1000))
ERROR: integer division error
 in randu at random.jl:158
 in rand at random.jl:178
 in rand at random.jl:187

edit: GregS提到2^1000会绕零。实际上,2^1000的结果是零,所以上面的代码是错误的。但使用BigInt(2)^1000不工作:

julia> rand(BigInt(1):BigInt(2)^1000)
ERROR: InexactError()
 in convert at gmp.jl:108
 in colon at range.jl:38
julia> rand(BigInt(1):BigInt(2)^BigInt(1000))
ERROR: InexactError()
 in convert at gmp.jl:108
 in colon at range.jl:38
完成这件事最快的方法是什么?(三个数字应均匀分布)

谢谢!

如果您使用call,这毕竟是可用的。我相信在某些时候它会很容易,但现在有一种方法可以做到这一点,我没有找到从基础开始使用它的方法,但如果事情发生变化,我会修改。有2个电话,需要作出这一工作。从gmp的文档中,我选择了mpz_urandomm

GMP支持

-函数:void mpz_urandomm (mpz_t rop, gmp_randstate_t state, const mpz_t n)生成一个0 ~ n-1(含)的均匀随机整数

变量状态必须在调用gmp_randinit函数(随机状态初始化)之前被初始化。

你必须首先初始化随机数生成器,我这样做不是最优的,将更新一些改进。

-函数:void gmp_randinit_default (gmp_randstate_t state)使用默认算法初始化状态。这将是速度和随机性之间的折衷,建议用于没有特殊要求的应用程序。当前是gmp_randinit_mt。

调用方法

初始化RNG

没有一个优雅的方式来声明gmp_randstate_t,只是声明一个大缓冲区。这很重要,否则会发生段错误。

julia> buffer = Array(Uint8,32);
julia> ccall((:__gmp_randinit_default,:libgmp),Void,(Ptr{Uint8},),buffer);

生成随机数

创建BigInt, x来存储结果

julia> x = BigInt(0)
0

设置y为MaxRange

julia> y = BigInt(2)^1000

10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376

生成随机x

julia> ccall((:__gmpz_urandomm,:libgmp),Void,(Ptr{BigInt},Ptr{Uint8},Ptr{BigInt}),&x,buffer,&y)

验证

朱莉娅> x9301165293246235069759966068146313776551258669855356477271940698500929939755418247622530571466332330697816620308003246225290293476785304004840090056840661553451916748315356563734257724978000166406621823207925733850455027807451108123161768212073821382033500073069184011344280494573919716117539236653172

等等……

julia> ccall((:__gmpz_urandomm,:libgmp),Void,(Ptr{BigInt},Ptr{Uint8},Ptr{BigInt}),&x,buffer,&y)

朱莉娅> x5073599723113217446035606058203362324610326948685707674578205618189982426100515602680640230141018758328161278469759835943678360952795440512680380424413847653984694781421269745198616340362470820037933917709243387214511018480191308767310495781355601069937334945556566243556239048498564021992916827796124

这是一个旧的帖子,但是Julia现在使解决这个问题变得容易了。

例如,使用Julia 1.1.0(我已经为我正在做的一个名为JulieGo的项目定制了Julia REPL)。答案在常规的Julia REPL中应该是一样的。)

JulieGo>VERSION
v"1.1.0"
# Set seed to get same results again.
JulieGo>rng_info = Random.seed!(12345);
# Here is an answer in Julia 1.1.0.    
JulieGo>r1 = rand(big"1":big"2"^1000)
8986172793045621030349078950793778042482316869955566599310906000510726536023373350273552788410494562
1437227128958537257991121543058284731429268230113459330352619981122924349300809967077942239392386680
0757367867423923215806277494619337596597641816501707643360907546040909561196900772512609868177829183
# Print result in an easy to read format.    
JulieGo>using Printf
JulieGo>@printf "%0.3E" float(r1)
8.986E+299
# Reseed the RNG.
JulieGo>rng_info = Random.seed!(12345);
# Try again.    
JulieGo>r2 = rand(big"1":big"2"^1000)
8986172793045621030349078950793778042482316869955566599310906000510726536023373350273552788410494562
1437227128958537257991121543058284731429268230113459330352619981122924349300809967077942239392386680
0757367867423923215806277494619337596597641816501707643360907546040909561196900772512609868177829183
# The result is the same.
JulieGo>@printf "%0.3E" float(r2)
8.986E+299
JulieGo>r1 == r2
true
# This also works.
# Reseed the RNG.
JulieGo>rng_info = Random.seed!(12345);
# Only the 2 needs to be specified explicitly as a big int.
JulieGo>r3 = rand(1:big"2"^1000)
898617279304562103034907895079377804248231686995556659931090600051072653602337335027355278841049456
143722712895853725799112154305828473142926823011345933035261998112292434930080996707794223939238668
075736786742392321580627749461933759659764181650170764336090754604090956119690077251260986817782918
JulieGo>r3 == r2
true

最新更新