Random.st
author claus
Fri, 05 Aug 1994 03:08:16 +0200
changeset 36 d046fe84ea67
parent 31 e223f3cf2995
child 65 8fdf5f30225f
permissions -rw-r--r--
*** empty log message ***

"======================================================================
|
| Copyright (C) 1988, 1989 Free Software Foundation, Inc.
| Written by Steve Byrne.
|
| This file is part of GNU Smalltalk.
|
| GNU Smalltalk is free software; you can redistribute it and/or modify it
| under the terms of the GNU General Public License as published by the Free
| Software Foundation; either version 1, or (at your option) any later version.
| 
| GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
| FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
| details.
| 
| You should have received a copy of the GNU General Public License along with
| GNU Smalltalk; see the file LICENSE.  If not, write to the Free Software
| Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
|
 ======================================================================"


"
|     Change Log
| ============================================================================
| Author       Date       Change 
| claus      10 Jan 94    added more comments, added 'contents'
| claus       5 Apr 90    brought into Smalltalk/X
| sbyrne     19 Sep 89    Converted to use real method categories.
| sbyrne      3 Jul 89    created.
|
"

Stream subclass:#Random
       instanceVariableNames:'seed'
       classVariableNames:''
       poolDictionaries:''
       category:'Magnitude-Numbers'
!

Random comment:'
Copyright (C) 1988, 1989 Free Software Foundation, Inc.
Written by Steve Byrne.

$Header: /cvs/stx/stx/libbasic2/Random.st,v 1.7 1994-08-05 01:07:09 claus Exp $
'!

!Random class methodsFor: 'documentation'!

copyright
"
======================================================================
|
| Copyright (C) 1988, 1989 Free Software Foundation, Inc.
| Written by Steve Byrne.
|
| This file is part of GNU Smalltalk.
|
| GNU Smalltalk is free software; you can redistribute it and/or modify it
| under the terms of the GNU General Public License as published by the Free
| Software Foundation; either version 1, or (at your option) any later version.
| 
| GNU Smalltalk is distributed in the hope that it will be useful, but WITHOUT
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
| FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
| details.
| 
| You should have received a copy of the GNU General Public License along with
| GNU Smalltalk; see the file LICENSE.  If not, write to the Free Software
| Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  
|
======================================================================

see notice in (Random>>documentation)
"
!

version
"
$Header: /cvs/stx/stx/libbasic2/Random.st,v 1.7 1994-08-05 01:07:09 claus Exp $
"
!

documentation
"
    random numbers - thanks to Steves GNU Smalltalk

    Notice: although being included here,
            this file is NOT covered by the ST/X license, but by
            the FSF copyLeft (see copyright method).

            You can redistribute it under the terms stated there ...
            Also, the price you pay for ST/X does not include a charge for
            this file - it has to be considered as a separate piece of
            software, which can be copied and given away without any 
	    restriction from my (CG) side.
"
! !

!Random class methodsFor: 'instance creation'!

new
    "return a new random generator"

    ^self basicNew setSeed
! !

!Random methodsFor:'testing'!

chiSquare
    "perform a chiSquare-test on the receiver"

    "returns on Sun3 93.40000000000009"
    ^self chiSquare: 1000 range: 100

    "Random new chiSquare"
!

chiSquare: n range: r
    | f t s |
    s := 1234567.
    f := Array new: r + 1.
    1 to: r + 1 do: [ :i | f at: i put: 0 ].
    n timesRepeat:
        [ s := (seed * 31415821) + 1 bitAnd: 16r3FFFFFFF.
          t := s \\ r.
          f at: t + 1 put: (f at: t + 1) + 1 ].
    t := 0.
    1 to: r do: [ :i | t := t + (f at: i) squared ].
    ^r asFloat * t / n - n
!

atEnd
    "instances of random can always give more numbers"

    ^false
! !

!Random methodsFor: 'blocked methods'!

contents
    "blocked from use - contents makes no sense for random generators"

    self shouldNotImplement
!

nextPut: value
    "blocked from use - it makes no sense for randoms"

    self shouldNotImplement
! !

!Random methodsFor: 'accessing-reading'!

nextInteger
    "return the next integral random number,
     in the range 0 .. 16r3FFFFFFF.
     From Sedgewick's 'Algorithms', based on Lehmer's method"

    "the times: is a kludge - times does not convert to LargeInteger on overflow"
    seed := (seed times:31415821) + 1 bitAnd: 16r3FFFFFFF.
    ^ seed

    "|r|
     r := Random new.
     Transcript showCr:r nextInteger.
     Transcript showCr:r nextInteger.
     Transcript showCr:r nextInteger.
     Transcript showCr:r nextInteger.
    "
!

next
    "return the next random number in the range 0..1"

    seed := (seed times:31415821) + 1 bitAnd: 16r3FFFFFFF.
    ^ self nextInteger / 16r3FFFFFFF asFloat

    "|r|
     r := Random new.
     Transcript showCr:r next.
     Transcript showCr:r next.
     Transcript showCr:r next.
     Transcript showCr:r next.
    "
!

nextBoolean
    "return true or false by random"

    "thanks to Peter Deutsch ..."
    seed := (seed times:31415821) + 1 bitAnd: 16r3FFFFFFF.
    ^ seed < 16r20000000

    "|r|
     r := Random new.
     Transcript showCr:r nextBoolean.
     Transcript showCr:r nextBoolean.
     Transcript showCr:r nextBoolean.
     Transcript showCr:r nextBoolean.
    "
!

nextBetween:start and:stop
    "return a random between start and stop.
     claus: the original GNU version has a bug in returning values
     from the interval [start .. stop+1]"

    |rnd|

    rnd := self next.
    rnd := rnd * (stop asFloat - start asFloat + 1.0).
    rnd := rnd + start asFloat.
    ^ rnd

    "|r|
     r := Random new.
     Transcript showCr:(r nextBetween:1 and:10).
     Transcript showCr:(r nextBetween:1 and:10).
     Transcript showCr:(r nextBetween:1 and:10).
     Transcript showCr:(r nextBetween:1 and:10).
    "
!

nextIntegerBetween:start and:stop
    "return an integral random between start and stop"

    |rnd|

    rnd := self next.
    rnd := rnd * (stop asFloat - start asFloat + 1.0).
    ^ (rnd + start) truncated.

    "|r|
     r := Random new.
     Transcript showCr:(r nextIntegerBetween:1 and:10).
     Transcript showCr:(r nextIntegerBetween:1 and:10).
     Transcript showCr:(r nextIntegerBetween:1 and:10).
     Transcript showCr:(r nextIntegerBetween:1 and:10).
    "
!

nextMatchFor: aNumber
    "generate the next random, return true iff it has the same
     value as aNumber. Redefined to avoid endless reading."

    ^self next = aNumber
! !


!Random methodsFor: 'private'!

setSeed
    "set the initial seed value based on the current time"

    seed := Time secondClock bitAnd: 16r3FFFFFFF
! !