(* ************************************ Генератор какбыслучайных чисел, Линейный конгруэнтный метод, алгоритм Лемера. Вадим Исаев, 2020 ------------------------------- Generator pseudorandom numbers, Linear congruential generator, Algorithm by D. H. Lehmer. Vadim Isaev, 2020 *************************************** *) MODULE Rand; IMPORT HOST, Math; CONST RAND_MAX = 2147483647; VAR seed: INTEGER; PROCEDURE Randomize*; BEGIN seed := HOST.GetTickCount() END Randomize; (* Целые какбыслучайные числа до RAND_MAX *) PROCEDURE RandomI* (): INTEGER; CONST a = 630360016; BEGIN seed := (a * seed) MOD RAND_MAX RETURN seed END RandomI; (* Какбыслучайные числа с плавающей запятой от 0 до 1 *) PROCEDURE RandomR* (): REAL; RETURN FLT(RandomI()) / FLT(RAND_MAX) END RandomR; (* Какбыслучайное число в диапазоне от 0 до l. Return a random number in a range 0 ... l *) PROCEDURE RandomITo* (aTo: INTEGER): INTEGER; RETURN FLOOR(RandomR() * FLT(aTo)) END RandomITo; (* Какбыслучайное число в диапазоне. Return a random number in a range *) PROCEDURE RandomIRange* (aFrom, aTo: INTEGER): INTEGER; RETURN FLOOR(RandomR() * FLT(aTo - aFrom)) + aFrom END RandomIRange; (* Какбыслучайное число. Распределение Гаусса *) PROCEDURE RandG* (mean, stddev: REAL): REAL; VAR U, S: REAL; BEGIN REPEAT U := 2.0 * RandomR() - 1.0; S := Math.sqrr(U) + Math.sqrr(2.0 * RandomR() - 1.0) UNTIL (1.0E-20 < S) & (S <= 1.0) RETURN Math.sqrt(-2.0 * Math.ln(S) / S) * U * stddev + mean END RandG; BEGIN seed := 654321 END Rand.