Chromium Code Reviews| 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 |