OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/base/utils/random-number-generator.h" | 5 #include "src/base/utils/random-number-generator.h" |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 | 9 |
10 #include <new> | 10 #include <new> |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 } | 95 } |
96 } | 96 } |
97 | 97 |
98 | 98 |
99 double RandomNumberGenerator::NextDouble() { | 99 double RandomNumberGenerator::NextDouble() { |
100 return ((static_cast<int64_t>(Next(26)) << 27) + Next(27)) / | 100 return ((static_cast<int64_t>(Next(26)) << 27) + Next(27)) / |
101 static_cast<double>(static_cast<int64_t>(1) << 53); | 101 static_cast<double>(static_cast<int64_t>(1) << 53); |
102 } | 102 } |
103 | 103 |
104 | 104 |
105 int64_t RandomNumberGenerator::NextInt64() { | |
106 int64_t lo = static_cast<int64_t>(Next(32)); | |
107 int64_t hi = static_cast<int64_t>(Next(32)); | |
108 return (lo & 0xffffffff) | (hi << 32); | |
109 } | |
Benedikt Meurer
2014/10/08 11:40:12
This is undefined behaviour in C++. Should be:
ui
m.m.capewell
2014/10/08 17:35:02
Done.
| |
110 | |
111 | |
105 void RandomNumberGenerator::NextBytes(void* buffer, size_t buflen) { | 112 void RandomNumberGenerator::NextBytes(void* buffer, size_t buflen) { |
106 for (size_t n = 0; n < buflen; ++n) { | 113 for (size_t n = 0; n < buflen; ++n) { |
107 static_cast<uint8_t*>(buffer)[n] = static_cast<uint8_t>(Next(8)); | 114 static_cast<uint8_t*>(buffer)[n] = static_cast<uint8_t>(Next(8)); |
108 } | 115 } |
109 } | 116 } |
110 | 117 |
111 | 118 |
112 int RandomNumberGenerator::Next(int bits) { | 119 int RandomNumberGenerator::Next(int bits) { |
113 DCHECK_LT(0, bits); | 120 DCHECK_LT(0, bits); |
114 DCHECK_GE(32, bits); | 121 DCHECK_GE(32, bits); |
115 // Do unsigned multiplication, which has the intended modulo semantics, while | 122 // Do unsigned multiplication, which has the intended modulo semantics, while |
116 // signed multiplication would expose undefined behavior. | 123 // signed multiplication would expose undefined behavior. |
117 uint64_t product = static_cast<uint64_t>(seed_) * kMultiplier; | 124 uint64_t product = static_cast<uint64_t>(seed_) * kMultiplier; |
118 // Assigning a uint64_t to an int64_t is implementation defined, but this | 125 // Assigning a uint64_t to an int64_t is implementation defined, but this |
119 // should be OK. Use a static_cast to explicitly state that we know what we're | 126 // should be OK. Use a static_cast to explicitly state that we know what we're |
120 // doing. (Famous last words...) | 127 // doing. (Famous last words...) |
121 int64_t seed = static_cast<int64_t>((product + kAddend) & kMask); | 128 int64_t seed = static_cast<int64_t>((product + kAddend) & kMask); |
122 seed_ = seed; | 129 seed_ = seed; |
123 return static_cast<int>(seed >> (48 - bits)); | 130 return static_cast<int>(seed >> (48 - bits)); |
124 } | 131 } |
125 | 132 |
126 | 133 |
127 void RandomNumberGenerator::SetSeed(int64_t seed) { | 134 void RandomNumberGenerator::SetSeed(int64_t seed) { |
128 initial_seed_ = seed; | 135 initial_seed_ = seed; |
129 seed_ = (seed ^ kMultiplier) & kMask; | 136 seed_ = (seed ^ kMultiplier) & kMask; |
130 } | 137 } |
131 | 138 |
132 } } // namespace v8::base | 139 } } // namespace v8::base |
OLD | NEW |