(* ************************************ Генератор какбыслучайных чисел, Линейный конгруэнтный метод, алгоритм Лемера. Вадим Исаев, 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; (* Целые какбыслучайные числа 0..RAND_MAX-1 *) 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..aTo-1 Return a random number in a range 0..aTo-1 *) 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 + 1)) + 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.