Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import "dart:typed_data"; | 5 import "dart:typed_data"; |
| 6 | 6 |
| 7 // A VM patch of the dart:math library. | 7 // A VM patch of the dart:math library. |
| 8 | 8 |
| 9 // If [x] is an [int] and [exponent] is a non-negative [int], the result is | 9 // If [x] is an [int] and [exponent] is a non-negative [int], the result is |
| 10 // an [int], otherwise the result is a [double]. | 10 // an [int], otherwise the result is a [double]. |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 static const kSTATE_HI = 1; | 61 static const kSTATE_HI = 1; |
| 62 | 62 |
| 63 _Random._internal(state) { | 63 _Random._internal(state) { |
| 64 _state[kSTATE_LO] = state & _MASK_32; | 64 _state[kSTATE_LO] = state & _MASK_32; |
| 65 _state[kSTATE_HI] = state >> 32; | 65 _state[kSTATE_HI] = state >> 32; |
| 66 } | 66 } |
| 67 | 67 |
| 68 // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32. | 68 // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32. |
| 69 // http://en.wikipedia.org/wiki/Multiply-with-carry | 69 // http://en.wikipedia.org/wiki/Multiply-with-carry |
| 70 // The constant A is selected from "Numerical Recipes 3rd Edition" p.348 B1. | 70 // The constant A is selected from "Numerical Recipes 3rd Edition" p.348 B1. |
| 71 int _nextInt32() { | 71 int _nextState() { |
|
zra
2013/05/20 23:38:17
return type should be void?
srdjan
2013/05/20 23:48:25
Done.
| |
| 72 var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64; | 72 var state = ((_A * (_state[kSTATE_LO])) + _state[kSTATE_HI]) & _MASK_64; |
| 73 _state[kSTATE_LO] = state & _MASK_32; | 73 _state[kSTATE_LO] = state & _MASK_32; |
| 74 _state[kSTATE_HI] = state >> 32; | 74 _state[kSTATE_HI] = state >> 32; |
| 75 return _state[kSTATE_LO]; | |
| 76 } | 75 } |
| 77 | 76 |
| 78 int nextInt(int max) { | 77 int nextInt(int max) { |
| 79 if (max <= 0 || max > _POW2_32) { | 78 // TODO(srdjan): Remove the 'limit' check once optimizing comparison of |
| 79 // Smi-s with Mint constants. | |
| 80 final limit = 0x3FFFFFFF; | |
| 81 if (max <= 0 || ((max > limit) && (max > _POW2_32))) { | |
| 80 throw new ArgumentError("max must be positive and < 2^32:" | 82 throw new ArgumentError("max must be positive and < 2^32:" |
| 81 " $max"); | 83 " $max"); |
| 82 } | 84 } |
| 83 if ((max & -max) == max) { | 85 if ((max & -max) == max) { |
| 84 // Fast case for powers of two. | 86 // Fast case for powers of two. |
| 85 return _nextInt32() & (max - 1); | 87 _nextState(); |
| 88 return _state[kSTATE_LO] & (max - 1); | |
| 86 } | 89 } |
| 87 | 90 |
| 88 var rnd32; | 91 var rnd32; |
| 89 var result; | 92 var result; |
| 90 do { | 93 do { |
| 91 rnd32 = _nextInt32(); | 94 _nextState(); |
| 95 rnd32 = _state[kSTATE_LO]; | |
| 92 result = rnd32 % max; | 96 result = rnd32 % max; |
| 93 } while ((rnd32 - result + max) >= _POW2_32); | 97 } while ((rnd32 - result + max) >= _POW2_32); |
| 94 return result; | 98 return result; |
| 95 } | 99 } |
| 96 | 100 |
| 97 double nextDouble() { | 101 double nextDouble() { |
| 98 return ((nextInt(1 << 26) << 27) + nextInt(1 << 27)) / _POW2_53_D; | 102 return ((nextInt(1 << 26) << 27) + nextInt(1 << 27)) / _POW2_53_D; |
| 99 } | 103 } |
| 100 | 104 |
| 101 bool nextBool() { | 105 bool nextBool() { |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 112 | 116 |
| 113 // Use a singleton Random object to get a new seed if no seed was passed. | 117 // Use a singleton Random object to get a new seed if no seed was passed. |
| 114 static var _prng = null; | 118 static var _prng = null; |
| 115 | 119 |
| 116 static int _nextSeed() { | 120 static int _nextSeed() { |
| 117 if (_prng == null) { | 121 if (_prng == null) { |
| 118 // TODO(iposva): Use system to get a random seed. | 122 // TODO(iposva): Use system to get a random seed. |
| 119 _prng = new Random(new DateTime.now().millisecondsSinceEpoch); | 123 _prng = new Random(new DateTime.now().millisecondsSinceEpoch); |
| 120 } | 124 } |
| 121 // Trigger the PRNG once to change the internal state. | 125 // Trigger the PRNG once to change the internal state. |
| 122 return _prng._nextInt32(); | 126 _prng._nextState(); |
| 127 return _prng._state[kSTATE_LO]; | |
| 123 } | 128 } |
| 124 } | 129 } |
| OLD | NEW |