|
发表于 2018-7-4 17:50:27
|
显示全部楼层
下面是EV3随机模块调用函数的源代码。
void Random(void)
{
DATA16 Min;
DATA16 Max;
DATA16 Result;
Min = *(DATA16*)PrimParPointer();
Max = *(DATA16*)PrimParPointer();
Result = (DATA16)rand();
if (Result < 0)
{
Result = 0 - Result;
}
Result = (((Result * (Max - Min)) + 16383) / 32767);
Result += Min;
*(DATA16*)PrimParPointer() = Result;
}
Random这个函数最终也是调用的C语言的库函数,rand()。我们都知道rand()函数会从0~32767里面随机选出一个数。
重点看这一步。
Result = (((Result * (Max - Min)) + 16383) / 32767);
Result += Min;
如题主所说,我们想从1~3里面随机取数。 即max = 3, min = 1, max - min = 2
假设随机函数rand()的返回值是 a;而我们最终获得的返回值是b。
由源代码可知
式① (a*2+16383)/32767 + 1 = b
注意其中的斜杠算符'/‘是整除符号。 比如 10/3=3,余数直接略掉。
由式① 可以求出
b = 1时, 0<= a <= 8191
b = 2时, 8192<= a <= 24575
b = 3 时, 24576<= a <= 32767
尽管rand()函数是伪随机函数,但是基本可以认为是均匀分布。可以计算出 b的概率分布如下:
b = 1 25%
b = 2 50%
b = 3 25%。
嗯,根本就不是均匀分布,不知道乐高开发人员为什么要这么写。
实际上,如果假设 max = n, min = 1; 那么b的概率函数P(b)将有如下规律
P(b=1) = P(b=n) = 1/((n-1)*2)
P (b=其他值) = 1/(n-1)
|
|