西门子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


posted @ 2022-03-27 21:12  生命在等待中延续  阅读(764)  评论(0编辑  收藏  举报