<div dir="ltr"><div><div>About instance variables, this could have been used to have several different instantiations of the same algorithm with different constants...<br></div>But given the fact that there isn&#39;t even an accessor for that purpose, we can effectively get rid of them.<br>
</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2013/9/23 Levente Uzonyi <span dir="ltr">&lt;<a href="mailto:leves@elte.hu" target="_blank">leves@elte.hu</a>&gt;</span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I put this to the Inbox, because the Trunk is unstable.<span class="HOEnZb"><font color="#888888"><br>
<br>
<br>
Levente</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
On Mon, 23 Sep 2013, <a href="mailto:commits@source.squeak.org" target="_blank">commits@source.squeak.org</a> wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
A new version of Kernel was added to project The Inbox:<br>
<a href="http://source.squeak.org/inbox/Kernel-ul.811.mcz" target="_blank">http://source.squeak.org/<u></u>inbox/Kernel-ul.811.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Kernel-ul.811<br>
Author: ul<br>
Time: 23 September 2013, 6:48:32.356 pm<br>
UUID: b32f1827-e63d-46dd-b6b9-<u></u>0a15355aac6a<br>
Ancestors: Kernel-nice.810<br>
<br>
Changed Random for faster instance creation and better randomness:<br>
- moved constants q, r, a and m to class variables. There&#39;s no need to calculate and store them in all instances. Haven&#39;t inlined them, so they are documented and defined in one place.<br>
- try to use #primUTCMicrosecondClock for seed generation<br>
- don&#39;t calculate seed, when the user provides it<br>
- updated constants in #bucketTest:, because machines are faster nowadays<br>
<br>
=============== Diff against Kernel-nice.810 ===============<br>
<br>
Item was changed:<br>
 Object subclass: #Random<br>
+       instanceVariableNames: &#39;seed&#39;<br>
+       classVariableNames: &#39;A M Q R&#39;<br>
-       instanceVariableNames: &#39;seed a m q r&#39;<br>
-       classVariableNames: &#39;&#39;<br>
        poolDictionaries: &#39;&#39;<br>
        category: &#39;Kernel-Numbers&#39;!<br>
<br>
 !Random commentStamp: &#39;nice 3/24/2010 07:38&#39; prior: 0!<br>
 This Random Number Generator graciously contributed by David N. Smith.  It is an adaptation of the Park-Miller RNG which uses Floats to avoid the need for LargeInteger arithmetic.<br>
<br>
 If you just want a quick random integer, use:<br>
                10 atRandom<br>
 Every integer interval can give a random number:<br>
                (6 to: 12) atRandom<br>
 SequenceableCollections can give randomly selected elements:<br>
                &#39;pick one of these letters randomly&#39; atRandom<br>
 SequenceableCollections also respond to shuffled, as in:<br>
                ($A to: $Z) shuffled<br>
<br>
 The correct way to use class Random is to store one in an instance or class variable:<br>
                myGenerator := Random new.<br>
 Then use it every time you need another number between 0.0 and 1.0 (excluding)<br>
                myGenerator next<br>
 You can also generate a positive integer<br>
                myGenerator nextInt: 10!<br>
<br>
Item was changed:<br>
 ----- Method: Random class&gt;&gt;bucketTest: (in category &#39;testing&#39;) -----<br>
 bucketTest: randy<br>
        &quot;Execute this:   Random bucketTest: Random new&quot;<br>
        &quot; A quick-and-dirty bucket test. Prints nbuckets values on the<br>
 Transcript.<br>
          Each should be &#39;near&#39; the value of ntries. Any run with any value<br>
 &#39;far&#39; from ntries<br>
          indicates something is very wrong. Each run generates different<br>
 values.<br>
          For a slightly better test, try values of nbuckets of 200-1000 or<br>
 more; go get coffee.<br>
          This is a poor test; see Knuth.   Some &#39;OK&#39; runs:<br>
                1000 1023 998 969 997 1018 1030 1019 1054 985 1003<br>
                1011 987 982 980 982 974 968 1044 976<br>
                1029 1011 1025 1016 997 1019 991 954 968 999 991<br>
                978 1035 995 988 1038 1009 988 993 976<br>
 &quot;<br>
        | nbuckets buckets ntrys |<br>
+       nbuckets := 200.<br>
-       nbuckets := 20.<br>
        buckets := Array new: nbuckets.<br>
        buckets atAllPut: 0.<br>
+       ntrys :=  1000.<br>
-       ntrys :=  100.<br>
        ntrys*nbuckets timesRepeat: [ | slot |<br>
                slot := (randy next * nbuckets) floor + 1.<br>
                buckets at: slot put: (buckets at: slot) + 1 ].<br>
        Transcript cr.<br>
        1 to: nbuckets do: [ :nb |<br>
                Transcript show: (buckets at: nb) printString, &#39; &#39; ]!<br>
<br>
Item was added:<br>
+ ----- Method: Random class&gt;&gt;initialize (in category &#39;class initialization&#39;) -----<br>
+ initialize<br>
+       &quot;Initialize the magic constants. All instances share these values. Use floats to avoid LargeInteger computations (it still gives about 3-4x speedup).&quot;<br>
+<br>
+       A := 16807.0. &quot; magic constant = 16807 &quot;<br>
+       M := 2147483647.0. &quot; magic constant = <a href="tel:2147483647" value="+12147483647" target="_blank">2147483647</a> &quot;<br>
+       Q := 127773.0. &quot;(m quo: a) asFloat.&quot;<br>
+       R  :=  2836.0 &quot;(m \\ a) asFloat.&quot;!<br>
<br>
Item was changed:<br>
 ----- Method: Random class&gt;&gt;seed: (in category &#39;instance creation&#39;) -----<br>
 seed: anInteger<br>
+       ^self basicNew seed: anInteger!<br>
-       ^self new seed: anInteger!<br>
<br>
Item was changed:<br>
 ----- Method: Random&gt;&gt;initialize (in category &#39;initialization&#39;) -----<br>
 initialize<br>
+<br>
+       | hash |<br>
+       hash := self hash.<br>
+       &quot;Set a reasonable Park-Miller starting seed&quot;<br>
+       seed := Time primUTCMicrosecondClock.<br>
+       seed = 0 ifFalse: [ &quot;Use the microsecond clock if possible.&quot;<br>
+               seed := (seed bitAnd: 16r3FFFFFFF) bitXor: hash ].<br>
+       [ seed = 0 ] whileTrue: [ &quot;Try again if ever get a seed = 0, or there&#39;s no microsecond clock.&quot;<br>
+               seed := (Time millisecondClockValue bitAnd: 16r3FFFFFFF) bitXor: hash ]!<br>
-       &quot; Set a reasonable Park-Miller starting seed &quot;<br>
-       [seed := (Time millisecondClockValue bitAnd: 16r3FFFFFFF) bitXor: self hash.<br>
-       seed = 0] whileTrue: [&quot;Try again if ever get a seed = 0&quot;].<br>
-<br>
-       a := 16r000041A7 asFloat.    &quot; magic constant =      16807 &quot;<br>
-       m := 16r7FFFFFFF asFloat.    &quot; magic constant = <a href="tel:2147483647" value="+12147483647" target="_blank">2147483647</a> &quot;<br>
-       q := (m quo: a) asFloat.<br>
-       r  := (m \\ a) asFloat.<br>
- !<br>
<br>
Item was changed:<br>
 ----- Method: Random&gt;&gt;next (in category &#39;accessing&#39;) -----<br>
 next<br>
        &quot;Answer a random Float in the interval [0 to 1).&quot;<br>
<br>
+       ^ (seed := self nextValue) / M!<br>
-       ^ (seed := self nextValue) / m!<br>
<br>
Item was changed:<br>
 ----- Method: Random&gt;&gt;nextValue (in category &#39;private&#39;) -----<br>
 nextValue<br>
        &quot;This method generates random instances of Integer      in the interval<br>
        0 to 16r7FFFFFFF. This method does NOT update the seed; repeated sends<br>
        answer the same value.<br>
        The algorithm is described in detail in &#39;Random Number Generators:<br>
        Good Ones Are Hard to Find&#39; by Stephen K. Park and Keith W. Miller<br>
        (Comm. Asso. Comp. Mach., 31(10):1192--1201, 1988).&quot;<br>
<br>
        | lo hi aLoRHi answer |<br>
+       hi := (seed quo: Q) asFloat.<br>
+       lo := seed - (hi * Q).  &quot; = seed rem: q&quot;<br>
+       aLoRHi := (A * lo) - (R * hi).<br>
-       hi := (seed quo: q) asFloat.<br>
-       lo := seed - (hi * q).  &quot; = seed rem: q&quot;<br>
-       aLoRHi := (a * lo) - (r * hi).<br>
        answer := (aLoRHi &gt; 0.0)<br>
                ifTrue:  [aLoRHi]<br>
+               ifFalse: [aLoRHi + M].<br>
-               ifFalse: [aLoRHi + m].<br>
        ^ answer!<br>
<br>
<br>
<br>
</blockquote>
<br>
</div></div></blockquote></div><br></div>