summaryrefslogtreecommitdiffstats
path: root/Lib/whrandom.py
blob: 2ce5f8f79ad4f8d576e377beaa9ab7da264f64e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#	WICHMANN-HILL RANDOM NUMBER GENERATOR
#
#	Wichmann, B. A. & Hill, I. D. (1982)
#	Algorithm AS 183: 
#	An efficient and portable pseudo-random number generator
#	Applied Statistics 31 (1982) 188-190
#
#	see also: 
#		Correction to Algorithm AS 183
#		Applied Statistics 33 (1984) 123  
#
#		McLeod, A. I. (1985)
#		A remark on Algorithm AS 183 
#		Applied Statistics 34 (1985),198-200
#
#
#	USE:
#	whrandom.random()	yields double precision random numbers 
#				uniformly distributed between 0 and 1.
#
#	whrandom.seed()		must be called before whrandom.random()
#				to seed the generator


#	Translated by Guido van Rossum from C source provided by
#	Adrian Baddeley.


# The seed
#
_seed = [0, 0, 0]


# Set the seed
#
def seed(x, y, z):
	_seed[:] = [x, y, z]


# Return the next random number in the range [0.0 .. 1.0)
#
def random():
	from math import floor		# floor() function
	#
	[x, y, z] = _seed
	x = 171 * (x % 177) - 2 * (x/177)
	y = 172 * (y % 176) - 35 * (y/176)
	z = 170 * (z % 178) - 63 * (z/178)
	#
	if x < 0: x = x + 30269
	if y < 0: y = y + 30307
	if z < 0: z = z + 30323
	#
	_seed[:] = [x, y, z]
	#
	term = float(x)/30269.0 + float(y)/30307.0 + float(z)/30323.0
	rand = term - floor(term)
	#
	if rand >= 1.0: rand = 0.0	# floor() inaccuracy?
	#
	return rand


# Initialize from the current time
#
def init():
	import time
	t = time.time()
	seed(t%256, t/256%256, t/65536%256)


# Make sure the generator is preset to a nonzero value
#
init()