OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 #include "vm/random.h" | 5 #include "vm/random.h" |
6 #include "vm/dart.h" | 6 #include "vm/dart.h" |
7 #include "vm/flags.h" | 7 #include "vm/flags.h" |
8 #include "vm/os.h" | 8 #include "vm/os.h" |
9 | 9 |
10 namespace dart { | 10 namespace dart { |
(...skipping 11 matching lines...) Expand all Loading... |
22 } | 22 } |
23 } | 23 } |
24 } | 24 } |
25 if (seed == 0) { | 25 if (seed == 0) { |
26 // We did not get a seed so far. As a fallback we do use the current time. | 26 // We did not get a seed so far. As a fallback we do use the current time. |
27 seed = OS::GetCurrentTimeMicros(); | 27 seed = OS::GetCurrentTimeMicros(); |
28 } | 28 } |
29 Initialize(seed); | 29 Initialize(seed); |
30 } | 30 } |
31 | 31 |
32 | |
33 void Random::Initialize(uint64_t seed) { | 32 void Random::Initialize(uint64_t seed) { |
34 ASSERT(seed != 0); | 33 ASSERT(seed != 0); |
35 // Crank the next state a couple of times. | 34 // Crank the next state a couple of times. |
36 _state = seed; | 35 _state = seed; |
37 NextState(); | 36 NextState(); |
38 NextState(); | 37 NextState(); |
39 NextState(); | 38 NextState(); |
40 NextState(); | 39 NextState(); |
41 } | 40 } |
42 | 41 |
43 | |
44 Random::Random(uint64_t seed) { | 42 Random::Random(uint64_t seed) { |
45 Initialize(seed); | 43 Initialize(seed); |
46 } | 44 } |
47 | 45 |
48 | |
49 Random::~Random() { | 46 Random::~Random() { |
50 // Nothing to be done here. | 47 // Nothing to be done here. |
51 } | 48 } |
52 | 49 |
53 // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32. | 50 // The algorithm used here is Multiply with Carry (MWC) with a Base b = 2^32. |
54 // http://en.wikipedia.org/wiki/Multiply-with-carry | 51 // http://en.wikipedia.org/wiki/Multiply-with-carry |
55 // The constant A is selected from "Numerical Recipes 3rd Edition" p.348 B1. | 52 // The constant A is selected from "Numerical Recipes 3rd Edition" p.348 B1. |
56 void Random::NextState() { | 53 void Random::NextState() { |
57 const uint64_t MASK_32 = 0xffffffff; | 54 const uint64_t MASK_32 = 0xffffffff; |
58 const uint64_t A = 0xffffda61; | 55 const uint64_t A = 0xffffda61; |
59 | 56 |
60 uint64_t state_lo = _state & MASK_32; | 57 uint64_t state_lo = _state & MASK_32; |
61 uint64_t state_hi = (_state >> 32) & MASK_32; | 58 uint64_t state_hi = (_state >> 32) & MASK_32; |
62 _state = (A * state_lo) + state_hi; | 59 _state = (A * state_lo) + state_hi; |
63 } | 60 } |
64 | 61 |
65 | |
66 uint32_t Random::NextUInt32() { | 62 uint32_t Random::NextUInt32() { |
67 const uint64_t MASK_32 = 0xffffffff; | 63 const uint64_t MASK_32 = 0xffffffff; |
68 NextState(); | 64 NextState(); |
69 return static_cast<uint32_t>(_state & MASK_32); | 65 return static_cast<uint32_t>(_state & MASK_32); |
70 } | 66 } |
71 | 67 |
72 } // namespace dart | 68 } // namespace dart |
OLD | NEW |