【求解】pascal到底是以什么方式生成随机数的
pascal吧
全部回复
仅看楼主
level 12
doveccl 楼主
昨天无聊用pascal生成随机数
结果发现在random(n)中生成的数大多接近于n,没有小的
而用其他语言生成的数就有大有小,分布较散,这是为什么呢?
以下是pascal的结果
以下是非pascal的结果
2013年04月04日 07点04分 1
level 12
doveccl 楼主
好吧我承认下面那个图的数普遍偏小
2013年04月04日 07点04分 2
壮我哉大VB
2013年05月15日 12点05分
level 9
管他什么方式。。。
2013年04月04日 08点04分 3
你有木有初始化“randomize”
2013年04月05日 02点04分
回复 fp4869 :呵呵~
2013年05月15日 12点05分
回复 fp4869 :不初始化下面的值都一样...显然randomize了
2014年02月02日 05点02分
level 12
没有初始化是有规律的,每次运行得到结果可能都一样。我猜它应该把计时的数据拿来用
2013年04月05日 03点04分 4
那是!
2013年04月06日 00点04分
level 5
Pascal所产生的是“伪随机数”(因为在计算机里是不可能实现完全的随机的),原理我记得是用了系统时间(毫秒数)以一种科(qi)学(pa)的算法来得出一个二进制数列,然后要用的时候再取出来再以一种科(qi)学(pa)的算法算出一个你要的值。
2013年04月05日 07点04分 5
我不了解![瞌睡]
2013年04月06日 00点04分
看不懂啊
2013年08月04日 10点08分
level 9
//system.inc中定义的random函数
function random(l:longint): longint;
begin
{otherwise we can return values = l (JM) }
if(l < 0) then
inc(l);
random := longint((int64(cardinal(genrand_MT19937))*l) shr 32);
end;
function random(l:int64): int64;
begin
{always call random, so the random generator cycles (TP-compatible) (JM) }
random := int64((qword(cardinal(genrand_MT19937)) or((qword(cardinal(genrand_MT19937)) shl 32))) and $7fffffffffffffff);
if(l<>0) then
random := random mod l
else
random := 0;
end;
{$ifndef FPUNONE}
function random: extended;
begin
random := cardinal(genrand_MT19937) * (extended(1.0)/(int64(1) shl 32));
end;
{$endif}
{$endif FPC_HAS_FEATURE_RANDOM}
2013年04月07日 22点04分 6
level 9
//可以看到,无论输入的是longint还是int64,生成的随机数都与函数genrand_MT19937有关
function genrand_MT19937: longint;
const
mag01 :array [0..1] of longint =(0, longint(MT19937MATRIX_A));
var
y:longint;
kk:longint;
begin
ifRandSeed<>OldRandSeed then
mti:=MT19937N+1;
if (mti>= MT19937N) { generate MT19937N longints at one time }
thenbegin
ifmti = (MT19937N+1) then // ifsgenrand_MT19937() has not been called,
begin
sgenrand_MT19937(randseed); //default initial seed is used
{ hack: randseed is not used more than once in this algorithm. Most }
{ user changes are re-initialisingreandseed with the value it had }
{ at the start -> with the"not", we will detect this change. }
{ Detecting other changes is notuseful, since the generated }
{ numbers will be differentanyway. }
randseed := not(randseed);
oldrandseed := randseed;
end;
forkk:=0 to MT19937N-MT19937M-1do begin
y:= (mt[kk] and MT19937UPPER_MASK) or (mt[kk+1] and MT19937LOWER_MASK);
mt[kk] := mt[kk+MT19937M]xor (y shr 1) xor mag01[y and $00000001];
end;
forkk:= MT19937N-MT19937M toMT19937N-2 do begin
y:= (mt[kk] and MT19937UPPER_MASK) or (mt[kk+1] and MT19937LOWER_MASK);
mt[kk] := mt[kk+(MT19937M-MT19937N)]xor (y shr 1) xor mag01[y and $00000001];
end;
y :=(mt[MT19937N-1] and MT19937UPPER_MASK) or (mt[0] and MT19937LOWER_MASK);
mt[MT19937N-1] := mt[MT19937M-1]xor (y shr 1) xor mag01[y and $00000001];
mti:= 0;
end;
y :=mt[mti]; inc(mti);
y := yxor (y shr 11);
y := yxor (y shl 7) and TEMPERING_MASK_B;
y := yxor (y shl 15) and TEMPERING_MASK_C;
y := yxor (y shr 18);
Result:= y;
end;
2013年04月07日 22点04分 7
level 9
//实际上生成随机数的过程是一个迭代函数的过程
VAR
mt :tMT19937StateArray;
const
mti:longint=MT19937N+1; // mti=MT19937N+1 means mt[] is not initialized
{ Initializing the array with a seed }
procedure sgenrand_MT19937(seed: longint);
var
i:longint;
begin
mt[0]:= seed;
for i:= 1 to MT19937N-1 do
begin
mt[i] := 1812433253 * (mt[i-1] xor (mt[i-1] shr 30)) + i;
end;
mti :=MT19937N;
end;
2013年04月07日 22点04分 8
level 9

procedure randomize;
begin randseed:=GetTickCount;
end;
2013年04月07日 22点04分 9
level 11
在计算机里的随机都是伪随机,其实你要是真闲得慌可以去找循环节。。。
你计算一下概率就知道了应该是趋于n-1的啊,用概率算也可以啊
2013年04月20日 13点04分 10
level 7
2013年05月10日 12点05分 11
level 5
按照楼主的意思要是小升初派位的程序是这么编的话[啊!]
2013年05月15日 12点05分 12
level 5
呵呵,对啊,我也是这样哈,100W以内,结果都是5、6位数,最小的也才是2793。。。
2013年05月15日 12点05分 13
level 5
线性同余法
2013年08月02日 10点08分 14
level 14
@ax_pokl
啊……
我根本看不懂!!!!!!!!!
解释一下!!!
2013年08月04日 10点08分 15
实际上System.pp中的randomize用的是GetTickCount,精确度只能到毫秒级别。也就是说,在一毫秒内生成的随机数有可能是“一样”的(虽然通过迭代可以消除这个问题,不过你懂的)。可以用QueryPerformanceFrequency(精确到百分之毫秒)或者直接用Intel芯片指令RDTSC精确到百万分之一秒。
2014年02月01日 02点02分
回复 ax_pokl :虽然看不大懂,但是谢谢了。…………………………
2014年02月01日 09点02分
level 14
楼主,你要从数学角度去看这个问题。
假设你是10^5以内的随机数,
那10^4以内占10%,
那10^3以内占1%,
那10^2以内占0.1%
……
2013年08月04日 12点08分 16
顶一个!
2014年02月01日 15点02分
level 8
(告诉我)
2013年08月05日 10点08分 18
level 12
说白了,随机数的生成:random(n)就是一个很大很大的数(称为种子)(int64和longint不一样的)mod n。
而如果调用了randomsize,就是将种子和某系统时间挂钩了
2013年08月05日 14点08分 19
level 9
//试试这段程序
{$ASMMODE INTEL}
program randseedtest;
var il,ih:DWORD;
i:QWORD;
begin
repeat
asm
rdtsc
mov il,eax
mov ih,edx
end;
i:=ih shl 16;
i:=i shl 16 or il;
randseed:=cardinal(il);
writeln(i:30,random:30:20);
until false;
end.
2014年02月01日 02点02分 20
level 11
你初始化了吗……
2014年02月02日 15点02分 21
1 2 尾页