Random.st
changeset 3026 a02198c26f88
parent 2459 efcb4bd16dc7
child 3060 5267b3c2754c
--- a/Random.st	Thu Jul 04 17:44:54 2013 +0200
+++ b/Random.st	Thu Jul 04 17:44:57 2013 +0200
@@ -486,15 +486,19 @@
 nextIntegerBetween:start and:stop
     "return an integral random number between start and stop"
 
-    |rnd|
+    |rnd range bytesNeeded|
 
-    rnd := self next.                               
-    rnd := rnd * ((stop - start) asFloat + 1.0).    
-    ^ rnd truncated + start
+    range := stop - start + 1.
+    bytesNeeded := (range highBit + 7) // 8.
+    "Fetch at least 2 bytes, otherwise we get some unbalanced distributions for small ranges"
+    bytesNeeded == 1 ifTrue:[bytesNeeded := bytesNeeded + 1].
+    rnd := (LargeInteger digitBytes:(self nextBytes:bytesNeeded)) compressed.
+    rnd := rnd \\ range.
+    ^ rnd + start
 
     "
      |r|
-     r := Random new.
+     r := self new.
      Transcript showCR:(r nextIntegerBetween:1 and:10).
      Transcript showCR:(r nextIntegerBetween:1 and:10).
      Transcript showCR:(r nextIntegerBetween:1 and:10).
@@ -503,12 +507,34 @@
 
     "
      |r bag|
-     r := Random new.
+     r := self new.
      bag := Bag new.
      1000000 timesRepeat:[
          bag add:(r nextIntegerBetween:-1 and:1).
      ].
-     Transcript showCR:bag contents
+     Transcript showCR:bag contents.
+    "
+
+    "
+     |r bag|
+     r := self new.
+     bag := Bag new.
+     1000000 timesRepeat:[
+         bag add:(r nextIntegerBetween:1 and:3).
+     ].
+     Transcript showCR:bag contents.
+     TestCase assert:(bag standardDeviation closeTo:(((3 squared - 1)/12) sqrt)).
+    "
+
+    "
+     |r bag|
+     r := self new.
+     bag := Bag new.
+     1000000 timesRepeat:[
+         bag add:(r nextIntegerBetween:1 and:10).
+     ].
+     Transcript showCR:bag contents.
+     TestCase assert:(bag standardDeviation closeTo:(((10 squared - 1)/12) sqrt)).
     "
 
     "Modified: / 21.8.1998 / 14:45:04 / cg"
@@ -616,9 +642,10 @@
 !Random class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic2/Random.st,v 1.44 2010-06-25 12:08:55 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/Random.st,v 1.45 2013-07-04 15:44:57 stefan Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libbasic2/Random.st,v 1.44 2010-06-25 12:08:55 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic2/Random.st,v 1.45 2013-07-04 15:44:57 stefan Exp $'
 ! !
+