//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}
//可以看到,无论输入的是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;
//实际上生成随机数的过程是一个迭代函数的过程 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;