Algorithm 将Int均匀随机范围缩放为双1

Algorithm 将Int均匀随机范围缩放为双1,algorithm,random,prng,Algorithm,Random,Prng,实际上,我有几个相互交织的问题。(如果有关系,我用C#) 首先。我有一个prng,它生成UInt32范围内的随机数,从0到UInt32.Max(包括最大值)。我希望尽可能保持一致性。得到[a,b],(a,b)双量程(如[0,1],[0,1],[0,1],[2,4],(-10,10])的主要思想是什么 我关心以下几点。我有424967296个prng结果。它小于[0,1]双范围-2^53中的数字。因此我从两位数字构造424967296个进制数,在[0,4294967295*4294967296+4

实际上,我有几个相互交织的问题。(如果有关系,我用C#)

首先。我有一个prng,它生成UInt32范围内的随机数,从0到UInt32.Max(包括最大值)。我希望尽可能保持一致性。得到[a,b],(a,b)双量程(如[0,1],[0,1],[0,1],[2,4],(-10,10])的主要思想是什么

我关心以下几点。我有424967296个prng结果。它小于[0,1]双范围-2^53中的数字。因此我从两位数字构造424967296个进制数,在[0,4294967295*4294967296+4294967295]中是随机的和一致的。此最大值大于1上的2^53,因此如果得到它,请将其丢弃,重新计算,使用mod 2^53并在中获得统一的数字,例如,[0,1]。在这里,我必须将最大值表示为双精度(假设没有Int64类型)-它有任何缺点吗

现在,如果我想得到[0,1 ],我认为结果的数量是(2 ^ 53)- 1。添加到最后的结果1 /(2 ^ 53)将产生随机双in(0,1]。为了得到(0,1),我考虑(2 ^ 53)-2的新结果,并将1 /(2 ^ 53)添加到0的结果。这些都是正确的吗?< /P> 但是如何获得接近或等于整个双量程的双量程?即使我像上面那样构造n元数,它也可能会大于double.Max。可能有些位移位/位掩码方法是可能的吗

第二,现在有双量程prng,其结果在[0,1]中。有可能得到[double.Min,double.Max]范围吗?总共有多少个双量程prng?如果有完整的双量程prng,那么最好的方法是什么?直接“映射”UInt范围或在之前缩放到[0,1]范围

第三,我找到了这个密码(http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/CODES/mt19937ar.c):

为什么a和b被移动到5和6,为什么在这之后a*67108864.0+b是一致的


谢谢。

好的随机数生成器会在所有位置产生随机位。某些类型的差随机数生成器会在低阶位产生差随机性。因此,如果您需要53位并生成64位,则需要丢弃11位最低阶位——在您发布的示例代码中,一个数字5位,另一个数字6位。现在u有一个26位的数字和一个27位的数字;2^26是67108864,2^53是9007199254740992,这应该解释为什么使用这些常数将这些数字缩放为[0,1]。(这是一个混合基数:第一个数字是67108864位,第二个数字是134217728位。)

(经常使用53位的原因是,它使数字在减法时对称——否则,当从1中减去2^-53和2^-64之间的值时,它们将消失。)

另外,当你有太多的比特时,你不应该重新取样——只要扔掉多余的比特(除非你的比特数少于一个)

无论如何,显而易见的方法会给你[0,1]。如果你想要(0,1),那就是1-[0,1]。如果你想要(0,1),如果你同时得到a=0和b=0,请再次采样。如果你想要[0,1],请注意,有1 in(2^53+1)的几率得到1,否则你就有[0,1]。你可以通过在中得到一个随机数来近似这一点[0,1)并检查它是否为零,如果是,则选择1作为答案,如果不是,则再次从[0,1]中选择。您的随机数生成器可能没有足够长的周期来更精确

 /* generates a random number on [0,1) with 53-bit resolution*/
 double genrand_res53(void) 
 { 
     unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; 
     return(a*67108864.0+b)*(1.0/9007199254740992.0); 
 }