我做了这样的实验——用 C 和 C# 制作了 1000 万个随机数。然后从随机整数的15位中计算每个位设置了多少次。(我选择了 15 位,因为 C 只支持最多 的随机整数0x7fff
)。
我得到的是:
我有两个问题:
为什么有 3 个最可能的位?
C
万一比特8,10,12
是最有可能的。并且C#
在位6,8,11
是最有可能的。似乎 C# 最可能的位大多被移动了 2 个位置,然后与 C 最可能的位相比。为什么是这样 ?因为 C# 使用其他 RAND_MAX 常量还是什么?
我的测试代码
C
:
void accumulateResults(int random, int bitSet[15]) {
int i;
int isBitSet;
for (i=0; i < 15; i++) {
isBitSet = ((random & (1<<i)) != 0);
bitSet[i] += isBitSet;
}
}
int main() {
int i;
int bitSet[15] = {0};
int times = 10000000;
srand(0);
for (i=0; i < times; i++) {
accumulateResults(rand(), bitSet);
}
for (i=0; i < 15; i++) {
printf("%d : %d\n", i , bitSet[i]);
}
system("pause");
return 0;
}
并测试代码C#
:
static void accumulateResults(int random, int[] bitSet)
{
int i;
int isBitSet;
for (i = 0; i < 15; i++)
{
isBitSet = ((random & (1 << i)) != 0) ? 1 : 0;
bitSet[i] += isBitSet;
}
}
static void Main(string[] args)
{
int i;
int[] bitSet = new int[15];
int times = 10000000;
Random r = new Random();
for (i = 0; i < times; i++)
{
accumulateResults(r.Next(), bitSet);
}
for (i = 0; i < 15; i++)
{
Console.WriteLine("{0} : {1}", i, bitSet[i]);
}
Console.ReadKey();
}
很感谢 !!顺便说一句,操作系统是 Windows 7、64 位架构和 Visual Studio 2010。
编辑
非常感谢@David Heffernan。我在这里犯了几个错误:
- C 和 C# 程序中的种子是不同的(C 使用零和 C# - 当前时间)。
- 我没有尝试使用不同的
Times
变量值来研究结果的可重复性。
以下是我在分析设置第一位的概率如何取决于调用 random() 的次数时得到的结果:
所以许多人注意到 - 结果不可重现,不应认真对待。(除非以某种形式确认 C/C# PRNG 足够好:-))。