--- 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 $'
! !
+