OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 // A part of the dart:math library. | |
6 | |
7 /** | |
8 * A random number generator. The default implementation supplies a stream of | |
9 * pseudo-random bits which is not suitable for cryptographic purposes. | |
10 */ | |
11 interface Random default _Random { | |
12 /** | |
13 * Creates a random-number generator. The optional parameter [seed] is used | |
14 * to initialize the internal state of the generator. The implementation of | |
15 * the random stream can change between releases of the library. | |
16 * | |
17 * Implementation note: The default implementation uses up to 64-bits of seed. | |
18 */ | |
19 Random([int seed]); | |
20 | |
21 // TODO(iposva): Do we really need this? | |
jjb
2012/05/16 21:50:10
No; when in doubt, leave it out. Upon reflection,
Ivan Posva
2012/05/16 22:54:34
Removed.
| |
22 /** | |
23 * Creates a random-number generator which does not change between releases. | |
24 * This random-number generator is potentially not as fast as the default | |
25 * implementation, but it allows creating repeatable random-number sequences. | |
26 * | |
27 * We anticipate that this random-number generator will be primarily used in | |
28 * testing. | |
29 */ | |
30 Random.stable([int seed]); | |
31 | |
32 /** | |
33 * Generates a positive random integer uniformly distributed on the range | |
34 * from 0, inclusive, to [max], exclusive. | |
35 * | |
36 * Implementation note: The default implementation supports [max] values | |
37 * between 1 and ((1<<32) - 1) inclusive. | |
38 */ | |
39 int nextInt(int max); | |
40 | |
41 /** | |
42 * Generates a positive random floating point value uniformly distributed on | |
43 * the range from 0.0, inclusive, to 1.0, exclusive. | |
44 */ | |
45 double nextDouble(); | |
46 | |
47 /** | |
48 * Generates a random boolean value. | |
49 */ | |
50 bool nextBool(); | |
51 } | |
52 | |
53 class _Random implements Random { | |
54 | |
55 _Random([int seed = null]) { | |
56 if (seed == null) { | |
57 seed = _nextSeed(); | |
58 } | |
59 do { | |
60 seed = (seed + 0x5A17) & _MASK_64; | |
61 } while (seed == 0); | |
62 _seed = seed; | |
63 } | |
64 | |
65 factory _Random.stable([int seed = null]) { | |
66 if (seed == null) { | |
67 // Nothing up my sleeve: Default seed value is the code review id. | |
68 seed = 10389150; | |
69 } | |
70 return new _Random(seed); | |
71 } | |
72 | |
jjb
2012/05/16 21:50:10
As per previous comment, I'd really like to see a
Ivan Posva
2012/05/16 22:54:34
Done.
| |
73 int _nextInt32() { | |
74 _seed = ((_A * (_seed & _MASK_32)) + (_seed >> 32)) & _MASK_64; | |
75 return _seed & _MASK_32; | |
76 } | |
77 | |
78 int nextInt(int max) { | |
79 // TODO(iposva): Check incoming arguments. | |
jjb
2012/05/16 21:50:10
For now, wouldn't it be sufficient to say:
if
Ivan Posva
2012/05/16 22:54:34
Added the check. Adding bits together eventually m
| |
80 if ((max & -max) == max) { | |
jjb
2012/05/16 21:50:10
Might want to put in a comment saying that this sp
Ivan Posva
2012/05/16 22:54:34
Done.
| |
81 return _nextInt32() & (max - 1); | |
82 } | |
83 | |
84 var rnd32; | |
85 var result; | |
86 do { | |
87 rnd32 = _nextInt32(); | |
88 result = rnd32 % max; | |
89 } while (rnd32 - result + max >= _POW2_32); | |
90 return result; | |
91 } | |
92 | |
93 double nextDouble() { | |
94 // TODO(iposva): Handle 53-bits of value. | |
jjb
2012/05/16 21:50:10
Can remove TODO, right? You are handling 53 bits.
Ivan Posva
2012/05/16 22:54:34
Done.
| |
95 return ((nextInt(1 << (26)) << 27) + nextInt(1 << 27)) / _POW2_53; | |
floitsch
2012/05/16 20:40:22
_POW2_53_D
Ivan Posva
2012/05/16 22:54:34
That's what I get for not rerunning tests before u
| |
96 } | |
97 | |
98 bool nextBool() { | |
99 return nextInt(1) == 0; | |
100 } | |
101 | |
102 static final _MASK_32 = (1 << 32) - 1; | |
103 static final _MASK_64 = (1 << 64) - 1; | |
104 static final _POW2_32 = 1 << 32; | |
105 static final _POW2_53_D = 1.0 * (1 << 53); | |
106 | |
107 static final _A = 0xffffda61; | |
108 | |
109 var _seed; | |
jjb
2012/05/16 21:50:10
This field should be called _state rather than see
Ivan Posva
2012/05/16 22:54:34
Done.
| |
110 | |
111 int _nextSeed() { | |
112 if (_prng == null) { | |
113 // TODO(iposva): Use system to get a random seed. | |
114 _prng = new _Random(new Date.now().value); | |
115 } | |
116 // Trigger the PRNG once to change the internal state. | |
117 _prng._nextInt32(); | |
118 return _prng._seed; | |
jjb
2012/05/16 21:50:10
Presumably the space between prng. and seed should
Ivan Posva
2012/05/16 22:54:34
Looks like an underscore to me.
| |
119 } | |
120 | |
121 static var _prng = null; | |
122 } | |
OLD | NEW |