我无法解决这个问题,哪个更随机?
rand()
或:
rand() * rand()
我发现它是一个真正的脑筋急转弯,您能帮我吗?
编辑:
凭直觉我知道数学答案将是它们是同样随机的,但是我忍不住想,如果您将两者相乘时两次“运行随机数算法”,那么您将创建的随机性远不止是它一次。
我无法解决这个问题,哪个更随机?
rand()
或:
rand() * rand()
我发现它是一个真正的脑筋急转弯,您能帮我吗?
编辑:
凭直觉我知道数学答案将是它们是同样随机的,但是我忍不住想,如果您将两者相乘时两次“运行随机数算法”,那么您将创建的随机性远不止是它一次。
Answers:
尽管每当您尝试发现伪随机变量或其乘积的随机性时,前面的答案都是正确的,但您应该意识到,尽管Random()通常是均匀分布的,但Random()* Random()却并非如此。
这是通过伪随机变量模拟的均匀随机分布样本:
BarChart[BinCounts[RandomReal[{0, 1}, 50000], 0.01]]
这是将两个随机变量相乘后得到的分布:
BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] *
RandomReal[{0, 1}, 50000], {50000}], 0.01]]
因此,两者都是“随机的”,但是它们的分布却大不相同。
虽然2 * Random()是均匀分布的:
BarChart[BinCounts[2 * RandomReal[{0, 1}, 50000], 0.01]]
Random()+ Random()不是!
BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] +
RandomReal[{0, 1}, 50000], {50000}], 0.01]]
该中心极限定理指出的和随机的()趋于一个正态分布的条款增加。
仅需四个字,您就可以:
BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000] +
Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000],
{50000}],
0.01]]
通过累加1、2、4、6、10和20个均匀分布的随机变量,可以看到从均匀分布到正态分布的道路:
编辑
几个学分
感谢Thomas Ahle在评论中指出最后两幅图像中所示的概率分布称为Irwin-Hall分布
rand()+rand()
,您最终将获得带有胖中心的“ 2d6”型分布。
我猜这两种方法都是随机的,尽管我的gutfeel会说rand() * rand()
随机性较低,因为它会播种更多的零。一rand()
经出现0
,总数就变成0
“随机性”都不是。
rand()
根据伪随机种子(通常基于当前时间,该时间总是在变化)生成可预测的一组数字。将序列中的两个连续数字相乘会生成一个不同但同样可预测的数字序列。
要解决这是否会减少冲突,答案是否定的。由于将两个数字相乘的影响,实际上会增加碰撞0 < n < 1
。结果将是较小的分数,导致结果偏向频谱的较低端。
一些进一步的解释。在下文中,“不可预测的”和“随机的”是指某人根据先前的数字猜测下一个数字将是什么的能力。一个甲骨文。
给定的种子x
将生成以下值列表:
0.3, 0.6, 0.2, 0.4, 0.8, 0.1, 0.7, 0.3, ...
rand()
将生成上面的列表,并rand() * rand()
生成:
0.18, 0.08, 0.08, 0.21, ...
两种方法将始终为相同的种子生成相同的数字列表,因此,甲骨文可以同样地预测它们。但是,如果您查看将两个调用相乘的结果,0.3
尽管原始序列分布良好,您会发现它们均处于不足状态。由于两个分数相乘的结果,这些数字是有偏差的。结果数始终较小,因此尽管仍然不可预测,但很有可能发生碰撞。
rand()+rand()+rand()...
,“随机性”越来越低(如果您是随机的,则表示均匀分布)。
rand()
实际上是随机的,不要试图“增强”它的随机性。不要多次设置种子。只要是半随机的种子,任何种子都是完美的。我见过的许多实现都使用UNIX时代作为种子,它每秒钟更改一次,并且每次更改都是唯一的。
过于简化来说明一点。
假设您的随机函数仅输出0
或1
。
random()
是之一(0,1)
,但是random()*random()
其中之一(0,0,0,1)
您可以清楚地看到,0
在第二种情况下获得的机会绝不等于获得的机会1
。
当我第一次发布此答案时,我想使其尽可能短,以便阅读该内容的人一眼就能了解random()
和之间的区别random()*random()
,但是我无法阻止自己回答原始的广告问题:
哪个更随机?
在于random()
,random()*random()
,random()+random()
,(random()+1)/2
或任何其他组合不导致固定的结果具有熵(在伪随机发生器的情况下,或在同一初始状态)相同的源,答案将是它们是同样的随机(所不同的在他们的分布中)。我们可以看的一个完美的例子是掷骰子游戏。您得到的数字是random(1,6)+random(1,6)
,我们都知道获得7的机会最高,但这并不意味着掷出两个骰子的结果比掷出一个骰子的结果或多或少是随机的。
这是一个简单的答案。考虑垄断。您掷出两个六个侧面的骰子(对于喜欢游戏符号的人则掷2d6)并取其总和。最常见的结果是7,因为有7种方式可以滚动7(1,6 2,5 3,4 4,3 5,2和6,1)。而2只能在1,1上滚动。很容易看出,滚动2d6与滚动1d12是不同的,即使范围相同(忽略在1d12上可以得到1的情况,该点也保持不变)。将结果相乘而不是相加,将会以类似的方式使结果偏斜,大多数结果出现在范围的中间。如果您要减少异常值,这是一个很好的方法,但它不利于进行均匀分布。
(奇怪的是,它也会增加低位滚动。假设您的随机性从0开始,您会看到在0处出现尖峰,因为它将使其他滚动变成0。考虑0和1(包括0和1)之间的两个随机数(包括)和相乘。如果任一结果为0,则无论其他结果如何,整个事物都将变为0。从中获得1的唯一方法是两卷均为1。实际上,这可能无关紧要但它使图表变得怪异。)
强制性的xkcd ...
考虑更多离散的数字可能会有所帮助。考虑要生成1到36之间的随机数,因此您决定最简单的方法是投掷两个6面公平的骰子。你得到这个:
1 2 3 4 5 6
-----------------------------
1| 1 2 3 4 5 6
2| 2 4 6 8 10 12
3| 3 6 9 12 15 18
4| 4 8 12 16 20 24
5| 5 10 15 20 25 30
6| 6 12 18 24 30 36
因此,我们有36个数字,但并不是所有数字都被公平地表示出来,有些根本没有出现。中心对角线(左下角到右上角)附近的数字出现频率最高。
描述骰子之间不公平分配的相同原理同样适用于0.0到1.0之间的浮点数。
大多数rand()实现都有一段时间。即,在经过大量调用之后,序列会重复。rand() * rand()
重复输出的顺序是一半的时间,因此从这个意义上讲它是“随机性较低”的。
另外,如果没有仔细的构造,对随机值执行算术往往会导致较少的随机性。上面引用“ rand()
+ rand()
+ rand()
...”(例如k倍)的海报实际上趋向于rand()
返回值范围的平均值的k倍。(这是一个随机步,其步长对称于该均值。)
为了具体起见,假设您的rand()函数返回范围为[0,1)的均匀分布的随机实数。(是的,此示例允许无限的精度。这不会改变结果。)您没有选择特定的语言,并且不同的语言可能会做不同的事情,但是下面的分析对rand的任何非正常实现进行了修改( )。乘积rand() * rand()
也处于[0,1)范围内,但不再均匀分布。实际上,乘积在间隔[0,1 / 4)中与在间隔[1 / 4,1)中一样。更多的乘法将使结果更趋向于零。这使得结果更加可预测。在粗笔中,更可预测==更少的随机性。
几乎所有对均匀随机输入的操作序列都是非均匀随机的,从而导致可预测性的提高。谨慎地解决了这一问题,但是在实际需要的范围内生成均匀分布的随机数会比浪费时间更容易。
“随机”与“更随机”有点像问哪个零更为零。
在这种情况下,rand
是PRNG,所以不是完全随机的。(实际上,如果知道种子,则完全可以预测)。将其乘以另一个值将使其不再或多或少是随机的。
真正的加密类型RNG实际上是随机的。通过任何类型的函数运行值都不能为其添加更多的熵,并且很可能会消除熵,从而使其不再具有随机性。
您要寻找的概念是“熵”,即一串位的无序度。就“最大熵”的概念而言,这个想法最容易理解。
具有最大熵的位字符串的近似定义是,不能用较短的位字符串准确地表示它(即,使用某种算法将较小的字符串扩展回原始字符串)。
最大熵与随机性的相关性源于以下事实:如果您“随机”选择一个数字,则几乎可以肯定会选择一个其位串接近具有最大熵的数字,即它不能被压缩。这是我们对“随机”数字的特征的最佳理解。
所以,如果你想使一个随机数出两个随机样本,这是“两次”为随机的,你会串连两个位串在一起。实际上,您只是将样本填充到双倍长度单词的高半部分和低半部分中。
从更实际的角度来看,如果您发现自己陷入了cr脚的rand(),它有时可以帮助将几个样本进行异或运算---即使该程序真的破了,也无济于事。
4
或二进制0100
可以压缩为零位。解压程序将仅返回“ 4”。随机性不会比这少。dilbert的问题是,我们不知道是否可以将其压缩为零位(通过始终返回“ 9”进行解压缩)。它也可能返回8,然后我们可以压缩到1位。解压缩方式:0-> 9,1-> 8。我们将有1个随机位。
接受的答案非常可爱,但是还有另一种方式可以回答您的问题。PachydermPuncher的答案已经采用了这种替代方法,我只是将其扩展一点。
思考信息理论的最简单方法是用最小的信息单位,即一位。
在C标准库中,rand()
返回0到范围内的整数,RAND_MAX
根据平台的不同,可以定义不同的限制。假设RAND_MAX
碰巧定义为某个整数2^n - 1
在哪里n
(在Microsoft的实现中恰好n
是15)。然后我们说一个好的实现将返回n
信息。
想象一下,rand()
通过抛硬币来找到一个位的值,然后重复进行直到它具有一批15位,来构造随机数。然后这些位是独立的(任何一位的值都不会影响同一批中其他位具有特定值的可能性)。因此,独立考虑的每个比特都像是一个介于0和1之间(含0和1)的随机数,并且在该范围内“均匀分布”(很可能是0和1)。
比特的独立性确保了一批比特所代表的数字也将均匀分布在它们的范围内。这在直观上很明显:如果有15位,则允许的范围是0到2^15 - 1
=32767。该范围内的每个数字都是唯一的位模式,例如:
010110101110010
如果这些位是独立的,则没有任何一种模式比其他任何模式都可能发生。因此,范围内所有可能的数字均具有同等可能性。因此,情况正好相反:如果rand()
产生均匀分布的整数,则这些数字由独立的位组成。
因此,rand()
可以将其想象为一条生产钻头的生产线,该生产线恰好可以以任意大小批量供应它们。如果您不喜欢它的大小,请将这些批次分成若干个小块,然后将它们按任意数量放回去(尽管如果您需要的特定范围不是2的幂,则需要缩小数量) ,到目前为止,最简单的方法是将其转换为浮点数。
返回到最初的建议,假设您要从15个批次增加到30个批次,要求rand()
输入第一个数字,将其位移15位,然后再添加一个rand()
。这是在rand()
不影响平均分配的情况下合并两个呼叫的一种方法。之所以起作用,是因为您放置信息的位置之间没有重叠。
这与rand()
通过乘以常数“拉伸”范围非常不同。例如,如果您想将范围扩大一倍,则rand()
可以乘以2-但是现在您将永远只能获得偶数,而永远不会获得奇数!这并不完全是平稳的分布,并且可能取决于应用程序,这可能是一个严重的问题,例如,类似轮盘赌的游戏据称允许奇/偶下注。(通过对位进行思考,您将直观地避免该错误,因为您意识到乘以2等于将位向左移动(更大的意义)等于一个位置并用零填充间隙。因此,显然信息量是相同的-它只是移动了一点。)
在浮点数应用中无法抓住这样的数字范围的差距,因为浮点范围固有地在其中存在根本无法表示的差距:每两个可表示的浮点之间的差距中存在无限数量的缺失实数点号!因此,我们无论如何都必须学习与他人相处。
正如其他人所警告的那样,直觉在这方面是有风险的,特别是因为数学家无法抗拒实数的诱惑,实数令人生厌,这些东西充满了肮脏的无限性和明显的悖论。
但是,至少如果您认为它有点用词,那么您的直觉可能会使您更进一步。比特确实很容易-甚至计算机也可以理解它们。
正如其他人所说,简单的简短答案是:不,它不是更加随机,但是它确实改变了分布。
假设您正在玩骰子游戏。您有一些完全公平,随机的骰子。如果在每次掷骰之前,先将两个骰子放在碗中,摇晃一下,随机选择一个骰子,然后掷那个骰子,掷骰子会“更随机”吗?显然,这没有什么区别。如果两个骰子都给出随机数,那么随机选择两个骰子之一将没有任何区别。无论哪种方式,您都将获得1到6之间的随机数,并且在足够数量的掷骰上会平均分配。
我想在现实生活中,如果您怀疑骰子可能不公平,这样的程序可能会有用。例如,如果骰子稍微不平衡,那么一个骰子的出现次数往往比1/6的次数多1,而另一个骰子的出现次数通常不正常的则多于6,那么在这两个骰子之间随机选择会掩盖偏见。(尽管在这种情况下,1和6仍然会超过2、3、4和5。嗯,我想这取决于失衡的性质。)
随机性有很多定义。随机序列的一个定义是它是由随机过程产生的一系列数字。根据这个定义,如果我掷出5次公平骰子并得到数字2、4、3、2、5,那是一个随机序列。如果我再将相同的模头掷出5次,得到1、1、1、1、1,那么那也是一个随机序列。
一些发布者指出,计算机上的随机函数并不是真正的随机函数,而是伪随机函数,如果您知道算法和种子,则它们是完全可预测的。的确如此,但是大多数时候是完全不相关的。如果我随机播放一副纸牌,然后一次将它们翻过来,那么这应该是随机的系列。如果有人偷看,结果将是完全可以预测的,但是根据大多数随机性的定义,这不会降低随机性。如果该系列通过了随机性的统计检验,那么我偷看卡片的事实不会改变这一事实。实际上,如果我们在猜测下一张卡片的能力上投入大量金钱,那么您偷看这些卡片的事实就非常相关。如果我们使用该系列来模拟访问我们网站的访问者的菜单,以测试系统的性能,那么您偷看的事实将毫无区别。(只要您不修改程序就可以利用此知识。)
编辑
我认为我无法将对Monty Hall问题的回答置为评论,所以我将更新答案。
对于那些没有阅读Belisarius链接的人,其要旨是:游戏比赛参赛者可以选择3个门。一个在后面是有价值的奖品,在其他后面则是一文不值的东西。他选择了1号门。在揭示它是赢家还是输家之前,主持人打开#3门以表明它是输家。然后,他为参赛者提供了切换到2号门的机会。参赛者应该这样做吗?
答案冒犯了许多人的直觉,那就是他应该改行。他最初的选择是获胜者的概率是1/3,另一扇门是获胜者的概率是2/3。我的最初直觉以及许多其他人的直觉是,切换不会有任何好处,赔率刚刚更改为50:50。
毕竟,假设在主机打开丢失门之后有人打开了电视。该人将看到剩下的两个关闭的门。假设他知道游戏的性质,他会说每个门有1/2倍的机会隐藏奖金。观众的赔率是1/2:1/2,而选手的赔率是1/3:2/3?
我真的不得不考虑这一点,以使我的直觉变成现实。要对此有所了解,请理解,当我们谈论此类问题中的概率时,是指在给定可用信息的情况下分配的概率。对于将奖品放在1号门后面的机组人员来说,奖品在1号门后面的概率为100%,在其他两个门中的任何一个后面的概率为零。
机组人员的赔率与参赛者的赔率不同,因为他知道参赛者不知道的东西,即他将奖品丢在了哪扇门上。同样,参赛者的赔率也不同于观看者的赔率,因为他知道观看者不知道的东西,即他最初选择的那扇门。这不是无关紧要的,因为主机对打开哪个门的选择不是随机的。他不会打开参赛者选择的门,也不会打开隐藏奖金的门。如果这些是同一扇门,那么他有两个选择。如果它们是不同的门,则只剩下一扇。
那么,我们如何得出1/3和2/3呢?当参赛者最初选择一扇门时,他有1/3的机会选择获胜者。我认为这很明显。这意味着其他门中的一个有2/3的机会是获胜者。如果主机游戏者在不提供任何其他信息的情况下进行切换的机会,则不会有任何收益。同样,这应该是显而易见的。但是一种看待它的方法是说他有2/3的机会会通过换牌获胜。但是他有2个选择。因此,每个人只有2/3除以2 = 1/3的获胜机会,这并不比他最初的选择更好。当然我们已经知道了最终结果,这只是以不同的方式进行计算。
但是现在主持人透露这两个选择之一不是获胜者。因此,在他没有选择的门有2/3的机会是获胜者的同时,他现在知道2个选择中的1个不是。另一个可能会也可能不会。因此,他不再拥有2/3除以2的权利。他对开着的门为零,对闭着的门为2/3。
考虑您有一个简单的硬币翻转问题,其中偶数被认为是正面,奇数被认为是背面。逻辑实现是:
rand() mod 2
在足够大的分布上,偶数的数量应等于奇数的数量。
现在考虑一下细微调整:
rand() * rand() mod 2
如果结果之一是偶数,则整个结果应该是偶数。考虑4种可能的结果(偶数*偶数=偶数,偶数*奇数=偶数,奇数*偶数=偶数,奇数*奇数=奇数)。现在,在足够大的分布范围内,答案应该甚至是75%的时间。
如果我是你,我敢打赌。
此评论实际上是在解释为什么不应该基于您的方法实现自定义随机函数,而不是讨论随机性的数学特性。
rand()%2
可能不是很随机;这实际上取决于低位的随机性,有些PRNG并不是很好。(当然,在某些语言中,您会得到浮点结果,rand()
因此您根本无法那样做……)
如果不确定随机数的组合会发生什么,可以使用从统计理论中学到的课程。
在OP的情况下,他想知道X * X = X ^ 2的结果是什么,其中X是沿着Uniform [0,1]分布的随机变量。我们将使用CDF技术,因为它只是一对一的映射。
由于X〜Uniform [0,1]的cdf为:f X(x)= 1我们想要变换Y <-X ^ 2因此y = x ^ 2求反x(y):sqrt(y)= x这使我们将x作为y的函数。接下来,找到导数dx / dy:d / dy(sqrt(y))= 1 /(2 sqrt(y))
Y的分布为:f Y(y)= f X(x(y))| dx / dy | = 1 /(2平方尺(y))
我们还没有完成,我们必须获取Y的域。因为0 <= x <1,0 <= x ^ 2 <1,所以Y在[0,1)范围内。如果要检查Y的pdf是否确实是pdf,请在域上对其进行集成:从0到1积分1 /(2 sqrt(y)),实际上,它弹出为1。此外,请注意所说的功能看起来就像是张贴的东西。
至于X 1 + X 2 + ... + X n,(其中X i〜统一[0,1]),我们就可以上诉到中心极限定理这适用于任何分布,其时刻存在。这就是Z检验实际存在的原因。
确定结果pdf的其他技术包括Jacobian变换(这是cdf技术的通用版本)和MGF技术。
编辑:作为澄清,请注意,我在说的是结果转换的分布,而不是其随机性。这实际上是一个单独的讨论。我实际得到的也是(rand())^ 2。对于rand()* rand()来说,它要复杂得多,在任何情况下都不会导致任何形式的均匀分布。
它并不十分明显,但rand()
通常比随机rand()*rand()
。重要的是,这对于大多数用途实际上并不十分重要。
但是首先,它们产生不同的分布。如果这是您想要的,这不是问题,但确实很重要。如果需要特定的分布,则忽略整个“更随机”的问题。那么,为什么rand()
随机性更高呢?
为什么是核心 rand()
更加随机(假设它会生成范围为[0..1]的浮点随机数,这是很常见的)是,将两个FP数与尾数中的大量信息相乘时,最后一些信息丢失;IEEE双精度浮点数中没有足够的位数来容纳从[0..1]中均匀随机选择的两个IEEE双精度浮点数中的所有信息,这些额外的信息位会丢失。当然,这无关紧要,因为您(可能)不会使用该信息,但是损失是真实的。产生哪种分布(即,使用哪种操作进行组合)也并不重要。每个随机数(最多)具有52位随机信息-
多数使用随机数时,使用的随机性甚至不及随机源中实际可用的随机性。获得良好的PRNG,不要太担心。(“良善”的程度取决于您使用它的方式;在进行蒙特卡洛模拟或加密时必须小心,但否则您可能会使用标准PRNG,因为通常这样会更快。)
通常,浮动随机数基于一种算法,该算法会产生一个介于零和某个范围之间的整数。这样,通过使用rand()* rand(),您实际上是在说int_rand()* int_rand()/ rand_max ^ 2-意味着您不包括任何质数/ rand_max ^ 2。
这极大地改变了随机分布。
rand()在大多数系统上均匀分布,并且难以预测是否正确植入。除非有特殊原因要对它进行数学运算(即,将分布调整为所需的曲线),否则请使用该函数。
rand()*rand()
小于rand()
- 的结果空间,因为它排除了质数。得到我的投票...
这些分布大多数发生是因为您必须限制或规范随机数。
我们将其归一化为所有正数,在一定范围内,甚至在分配的变量类型的内存大小约束内。
换句话说,因为我们必须将随机调用限制在0到X之间(X是变量的大小限制),所以我们会有一组在0到X之间的“随机”数字。
现在,当您将随机数添加到另一个随机数时,总和将在0到2X之间...这会使值偏离边缘点(将两个小数加在一起和两个大数加在一起的概率很小)您在较大的范围内有两个随机数)。
想想一下您有一个接近零的数字,然后将其与另一个随机数相加的情况,它肯定会变大并远离0(这对于大数将是正确的,并且不太可能具有两个大数(数字接近X)由Random函数返回两次。
现在,如果您要设置带有负数和正数(在零轴上平均分布)的随机方法,则不再是这种情况。
举例来说,RandomReal({-x, x}, 50000, .01)
那么您将在负数的正数侧得到均匀的数字分布,如果将随机数相加,它们将保持其“随机性”。
现在我不确定Random() * Random()
从负到正的跨度会发生什么...那将是一个有趣的图表...但是我现在必须重新开始编写代码。:-P
没有比随机性更强的东西了。它是随机的还是不是随机的。随机意味着“难以预测”。这并不意味着不确定。如果random()是随机的,则random()和random()* random()都是同等随机的。就随机性而言,分布无关紧要。如果出现非均匀分布,则意味着某些值比其他值更有可能;他们仍然是不可预测的。
由于涉及伪随机性,因此数量非常确定。但是,伪随机性在概率模型和仿真中通常就足够了。众所周知,使伪随机数生成器变得复杂只会使分析变得困难。不可能改善随机性;它通常会导致统计测试失败。
随机数的所需属性很重要:重复性和可重复性,统计随机性(通常)均匀分布且周期长。
关于随机数的转换:有人说过,两个或多个均匀分布的总和会导致正态分布。这是加性中心极限定理。只要所有分布都是独立且相同的,则无论源分布如何,都适用。该乘中心极限定理说,两个或多个独立且一致分布的随机变量的乘积是对数正态的。别人创建的图看起来是指数的,但实际上是对数正态的。因此random()* random()是对数正态分布的(尽管它可能不是独立的,因为数字是从同一流中提取的)。在某些应用中这可能是理想的。但是,通常最好生成一个随机数并将其转换为对数正态分布的数。Random()* random()可能难以分析。
有关更多信息,请访问www.performorama.org查阅我的书。该书正在建设中,但相关材料在那里。请注意,章节编号可能会随时间变化。第8章(概率论)-第8.3.1和8.3.3节,第10章(随机数)。
我们可以通过使用Kolmogorov复杂度来比较两个随机数数组, 如果不能压缩数字序列,那么它是在这个长度上可以达到的最大随机数...我知道,这种类型的测量更理论选项...
其实,当你想到它rand() * rand()
是少比随机rand()
。这就是为什么。
本质上,奇数与偶数相同。并且说0.04325是奇数,像0.388是偶数,0.4是偶数,而0.15是奇数,
这意味着它rand()
有相等的机会成为偶数或奇数小数。
另一方面,rand() * rand()
赔率的堆积方式有所不同。可以说:
double a = rand();
double b = rand();
double c = a * b;
a
并且b
两者都有50%的可能性是偶数或奇数。知道
意味着有一个75%的机会是c
为偶数,而只有25%的几率是奇数,使得价值rand() * rand()
超过预测的rand()
,因此随机的。
rand()
通常给出一个介于0和1之间的数字。谈论它是偶数还是奇数有意义吗?
0.2*0.2=0.04
这暗示了这种方法的根本缺陷:将两个double的53位相乘将得到大约100位的结果。但是这些位的后半部分将被丢弃。因此,当您以1作为其最低有效位的两个双精度数时,就无法说出其乘积的最低有效位。
rand()
的“偶数”和“奇数”定义与对分布有意义的“偶数”和“奇数”定义相同的rand()*rand()
。如果不是这种情况,则此参数失败。整数是正确的,但这些不是整数。
使用实现原始多项式的线性反馈移位寄存器(LFSR)。
结果将是2 ^ n个伪随机数的序列,即没有重复的序列,其中n是LFSR ....中的位数,从而导致均匀分布。
http://en.wikipedia.org/wiki/Linear_feedback_shift_register http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf
使用基于计算机时钟微秒的“随机”种子或文件系统中某些连续变化的数据的md5结果的子集。
例如,一个32位LFSR将从给定种子开始按顺序生成2 ^ 32个唯一编号(无2个相似)。顺序将始终是相同的顺序,但是对于不同的种子,起点将有所不同(很明显)。因此,如果播种之间可能重复的顺序不是问题,那么这可能是一个不错的选择。
我已经使用128位LFSR在硬件模拟器中使用种子生成随机测试,该种子是不断变化的系统数据上的md5结果。
正如其他人已经指出的那样,这个问题很难回答,因为我们每个人的脑海中都有自己的随机性。
这就是为什么,我强烈建议您花一些时间阅读本网站,以更好地了解随机性:
回到真正的问题。这个术语没有或多或少的随机性:
两者都只是随机出现!
在这两种情况下-只是rand()或rand()* rand()-情况都是一样的:数十亿个数字后,序列将重复(!)。对于观察者来说,这似乎是随机的,因为他不知道整个序列,但是计算机没有真正的随机源 -因此他也不会产生随机性。
例如:天气随机吗? 我们没有足够的传感器或知识来确定天气是否随机。
答案是取决于情况,希望rand()* rand()比rand()更随机,但是:
好吧,如果您检查以上任何一项,我建议您选择简单的“ rand()”。因为您的代码更具可读性(不会问自己为什么这么做,因为……好……超过2秒),所以易于维护(如果要用super_rand替换rand函数)。
如果您想要更好的随机性,我建议您从提供足够噪声(无线电静态)的任何源流式传输它,然后简单rand()
地就足够了。