//文件一:Random.st //用于产生随机数据的Function,这两个Function要联合使用,使用方法请参考Program sort中的使用。 //===Random============================================================ //SIEMENS AG //(c)Copyright 2007 All Rights Reserved //----------------------------------------------------------------------------------- // project name: // file name: Random.xml // library: LibBasic // system: // version: SIMOTION / Scout V4.1 // restrictions: // requirements: hardware independet, no technological packages // functionality: //----------------------------------------------------------------------------------- // change log table: // version date expert in charge changes applied // 01.00.00 not specified first created // 01.01.00 n.s. // 01.02.00 n.s. // 02.00.00 20.01.07 C. Fecke A&D B18 changes of form, variables, ... // 02.01.00 20.04.07 C. Fecke A&D B18 new assignment (LibBasic) // 02.02.00 07.08.07 C. Fecke A&D B18 Changes with reference to the styleguide V3.5 //=======================================================================
INTERFACE
// ----------- Export --------------------------------------------------------- FUNCTION FCRandom; // creates a random number between 0.1 to 1 (LREAL) FUNCTION FCRandomize; // inits the random generator
END_INTERFACE
IMPLEMENTATION
// ----------- Unit Global Constants ---------------------------------------- VAR_GLOBAL CONSTANT A_RANDOM : DINT := 16807; M_RANDOM : DINT := 2147483647; Q_RANDOM : DINT := 127773; // m div a R_RANDOM : DINT := 2836; // m mod a END_VAR
// ----------- Unit Global Variables ---------------------------------------- VAR_GLOBAL giRandomSeed : DINT := 1; END_VAR
FUNCTION FCRandom : LREAL // ---------------------------------------------------------------------------- // (A&D SE WKC A FA / Chemnitz) // ---------------------------------------------------------------------------- // functionality: creates a random number between 0.1 to 1 (LREAL) // You should init the generator with // FCRandomize(initial seed := 1..2147483646) before first call. // The same initial seed create the same numerical series. // Maxint must be greater than OR equal TO 2**31 - 1 // The created numerical series are uniformly distrubeted. // assignment: This function can be used in any kind of task. // ---------------------------------------------------------------------------- // change log table: // version date expert in charge changes applied // 02.00.00 20.01.07 C.Fecke A&D B18 changes of form, variables, ... // ============================================================================
// The following random number generator is an implementation of the // Minimum Standard Generator recommended in // Random Number Generators: Good ones are hard to find // Stephen K Park & Keith W Miller // Communications OF the ACM, Oct 88, Vol 31 No 10 1192 - 1201
VAR iLo : DINT; iHi : DINT; iTest : DINT; END_VAR
// calculate the new seed iHi := giRandomSeed / Q_RANDOM; iLo := giRandomSeed MOD Q_RANDOM; iTest := A_RANDOM * iLo - R_RANDOM * iHi; // map seed on positive DINT number range (1..2147483646) IF (iTest > 0) THEN // seed positiv ? giRandomSeed := iTest; ELSE // seed negativ ? giRandomSeed := iTest + M_RANDOM; END_IF;
// map random number (seed) on LREAL number range (0.0 .. 1.0) FCRandom := DINT_TO_LREAL(giRandomSeed) / DINT_TO_LREAL(M_RANDOM); RETURN;
END_FUNCTION
FUNCTION FCRandomize : VOID // ---------------------------------------------------------------------------- // (A&D SE WKC A FA / Chemnitz) // ---------------------------------------------------------------------------- // functionality: inits the random generator // assignment: This function can be used in any kind of task. // ---------------------------------------------------------------------------- // change log table: // version date expert in charge changes applied // 02.00.00 20.01.07 C.Fecke A&D B18 changes of form, variables, ... // ============================================================================ VAR_INPUT initSeed : DINT := 1; // integer between 1..2147483646 END_VAR
IF (initSeed < 1) THEN // seed too small ? giRandomSeed := 1; // limit seed ELSIF (initSeed > 2147483646) THEN // seed too big ? giRandomSeed := 2147483646; // limit seed ELSE // seed in range? giRandomSeed := initSeed; // take seed END_IF; RETURN;
END_FUNCTION
END_IMPLEMENTATION
// 文件二 :ST_Sort.st //该st文件中的程序Sort分配到backgroundtask INTERFACE USES random; FUNCTION FcShellSort; PROGRAM Sort;
//*********************************************************************** // function ShellSort //***********************************************************************
FUNCTION FcShellSort :ARRAY[0..8000]OF LREAL VAR_INPUT myArray : ARRAY[0..8000] OF LREAL; END_VAR (* VAR mySizeofArray: DINT; Increment : DINT; j,m: DINT; temp:LREAL; tempArray:ARRAY[0..8000] OF LREAL;
END_VAR*) tempArray:=myArray; //put the input array to a temp array mySizeofArray:=_sizeof(myArray)/_sizeof(myArray[0]);//get the size of array Increment:=mySizeofArray; //init Increment with the size of array
REPEAT Increment:=Increment/3+1; // the fomular to change the Increment FOR j:=Increment TO mySizeofArray-1 BY 1 DO
temp:=tempArray[j]; m:=j-Increment;
WHILE tempArray[m]>temp DO tempArray[m+Increment]:=tempArray[m]; m:=m-Increment;
IF m<0 OR m>=mySizeofArray THEN EXIT; END_IF;
END_WHILE; tempArray[m+Increment]:=temp;
END_FOR;
UNTIL Increment<=1 END_REPEAT; FcShellSort:=tempArray; END_FUNCTION
PROGRAM sort
VAR ArrayData:ARRAY[0..8000] OF LREAL; // to be sorted aData: ARRAY[0..8000] OF LREAL; // result after sorting i: DINT; CalculateTrig: r_trig; StartCal: BOOL:=FALSE; END_VAR CalculateTrig(clk:=StartCal); IF CalculateTrig.q THEN //start calculation //create an array of random data fcrandomize(initseed:=345); FOR i:=0 TO 8000 BY 1 DO ArrayData[i]:=fcrandom()*1000.0; END_FOR; //call the function to sort aData:= FcShellSort(ArrayData); END_IF;