西门子Protal_TIA SCL编程实例_伪随机数_线性同余法LCG
文章参考1:PLC产生随机数
文档参考2:西门子S7 -300线性同余法产生随机数
编写日期:2022年3月27日 11:27 周日
递归公式:RandSeed = (A * RandSeed + B) % M
A:乘数
B:增量
M:模数
LCG的周期最大为M,但大部分情况下都会少与M
要另LCG达到最大周期,应符合以下条件:
B,M互质;
M的所有质因数都能整除A-1;
若M是4的倍数,A-1也是;
A,B,N[0]都比M小;
A,B都是正整数;
FUNCTION "RandomLCG" : UInt
TITLE = RandomLCG
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : bootloader
VERSION : 0.1
//随机数_线性同余法LCG
VAR_INPUT
wMax : Int; // 随机数上限(不包含)
END_VAR
VAR_TEMP
DTL {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL; // 取得的系统时间
RET_V : Int; // 指令返回结果_取系统时间
seed : UDInt; // 种子
randseed : Real;
END_VAR
BEGIN
//PLC产生随机数_线性同余法
//方法来自西门子技术论坛:https://wenku.baidu.com/view/8db9e41d82eb6294dd88d0d233d4b14e84243e2b.html
//R(n+1) = [R(n) * a + b] mod c
//
//作者:bootloader
//2022年3月27日 19:29 周日
//--取得种子-------------------
#RET_V := RD_SYS_T(#DTL); //获取系统时间
#seed := #DTL.MINUTE + #DTL.SECOND + #DTL.NANOSECOND;
//-----------------------------
#seed := (#seed * 25173 + 13849) MOD 65536;
#randseed := UDINT_TO_REAL(#seed) / 65535.0;
//-----------------------------
#RandomLCG := REAL_TO_UINT(#randseed * INT_TO_REAL(#wMax));
END_FUNCTION