RAND.MOD 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. (*# check(stack=>off,
  2. index=>off,
  3. range=>off,
  4. overflow=>off,
  5. nil_ptr=>off) *)
  6. IMPLEMENTATION MODULE Rand;
  7. (******************************************************************************)
  8. (* Modify by John McMonagle 4/19/88 *)
  9. (* MODULA-2 Library *)
  10. (* *)
  11. (* LOGITECH SA, CH-1111 Romanel (Switzerland) *)
  12. (* LOGITECH Inc, Fremont, CA 94555 (USA) *)
  13. (* *)
  14. (* Module : Random, random number generator *)
  15. (* *)
  16. (* Release : 3.0 - July 87 *)
  17. (* *)
  18. (* Copyright (C) 1987 Logitech, All rights reserved *)
  19. (* *)
  20. (* Permission is hereby granted to registered users to use or abstract *)
  21. (* the following program in the implementation of customized versions. *)
  22. (* This permission does not include the right to redistribute the *)
  23. (* source code of this program. *)
  24. (* *)
  25. (******************************************************************************)
  26. (*----------------------------------------------------------------------------
  27. Algorithm: Additive congruential method (D.Knuth)
  28. ----------------------------------------------------------------------------*)
  29. (*/NOCHECK:O *)
  30. FROM EnvironUtils IMPORT
  31. GetTime;
  32. FROM NumTypes IMPORT
  33. Real8;
  34. CONST
  35. C = 53;(* was54 *)
  36. R = 65536.0;
  37. VAR
  38. a : ARRAY [0 .. C] OF CARDINAL;
  39. j, k : [0 .. C];
  40. PROCEDURE Next (): CARDINAL;
  41. BEGIN
  42. INC(a [k], a [j]);
  43. IF k = 0 THEN
  44. k := C;
  45. ELSE
  46. DEC(k);
  47. END;
  48. IF j = 0 THEN
  49. j := C;
  50. ELSE
  51. DEC(j);
  52. END;
  53. RETURN a [k];
  54. END Next;
  55. PROCEDURE RandomInit (seed : CARDINAL);
  56. VAR
  57. i, dummy : CARDINAL;
  58. BEGIN
  59. j := 23;(* was 24 *)
  60. k := 0;
  61. FOR i := 0 TO C DO
  62. a [i] := 0;
  63. END;
  64. a [k] := 31415 + seed;
  65. IF a [k] = 0 THEN
  66. a [k] := 31415;
  67. END;
  68. (* added 4/19/88 make sure seed is odd or all will be even *)
  69. IF NOT ODD(a[k])
  70. THEN
  71. INC(a[k]);
  72. END;
  73. FOR i := 0 TO 1219 DO(* was 1999 reduced as precision is not required *)
  74. dummy := Next ();
  75. END;
  76. END RandomInit;
  77. PROCEDURE RandomCard (bound : CARDINAL): CARDINAL;
  78. BEGIN
  79. IF bound = 0 THEN
  80. RETURN Next ();
  81. ELSE
  82. RETURN Next() MOD bound;
  83. (* RETURN TRUNC (FLOAT (bound) * FLOAT (Next ()) / R); *)
  84. END;
  85. END RandomCard;
  86. PROCEDURE RandomInt (bound : INTEGER): INTEGER;
  87. BEGIN
  88. RETURN INTEGER (RandomCard (CARDINAL (ABS (bound))));
  89. END RandomInt;
  90. (*
  91. PROCEDURE RandomReal () : Real8;
  92. BEGIN
  93. RETURN VAL(Real8,RandomCard (10000)) * 1.0E-16 +
  94. VAL(Real8,RandomCard (10000)) * 1.0E-12 +
  95. VAL(Real8,RandomCard (10000)) * 1.0E-08 +
  96. VAL(Real8,RandomCard (10000)) * 1.0E-04;
  97. END RandomReal;
  98. *)
  99. PROCEDURE Randomize;
  100. VAR
  101. minute,second,hundredths,
  102. i, j : CARDINAL;
  103. dummy: CARDINAL;
  104. str: ARRAY[0..40] OF CHAR;
  105. BEGIN
  106. GetTime(dummy,minute,second,hundredths,str);
  107. RandomInit (hundredths*second);
  108. j := minute;
  109. FOR i := 0 TO j DO
  110. dummy := Next ();
  111. END;
  112. END Randomize;
  113. BEGIN
  114. Randomize;
  115. (* FOR j:=0 TO C DO
  116. a[j]:=0;
  117. END;
  118. j:=0;
  119. k:=0; *)
  120. END Rand.