| ... | ... |
@@ -209,97 +209,97 @@ |
| 209 | 209 |
- cnt; |
| 210 | 210 |
--curr; ++cnt; |
| 211 | 211 |
if (curr == state) {
|
| 212 | 212 |
curr = state + length - 1; curr[0] = state[0]; --curr; |
| 213 | 213 |
cnt = 1; |
| 214 | 214 |
} |
| 215 | 215 |
} |
| 216 | 216 |
|
| 217 | 217 |
state[length - 1] = Word(1) << (bits - 1); |
| 218 | 218 |
} |
| 219 | 219 |
|
| 220 | 220 |
void copyState(const RandomCore& other) {
|
| 221 | 221 |
std::copy(other.state, other.state + length, state); |
| 222 | 222 |
current = state + (other.current - other.state); |
| 223 | 223 |
} |
| 224 | 224 |
|
| 225 | 225 |
Word operator()() {
|
| 226 | 226 |
if (current == state) fillState(); |
| 227 | 227 |
--current; |
| 228 | 228 |
Word rnd = *current; |
| 229 | 229 |
return RandomTraits<Word>::tempering(rnd); |
| 230 | 230 |
} |
| 231 | 231 |
|
| 232 | 232 |
private: |
| 233 | 233 |
|
| 234 | 234 |
|
| 235 | 235 |
void fillState() {
|
| 236 | 236 |
static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
|
| 237 | 237 |
static const Word loMask = RandomTraits<Word>::loMask; |
| 238 | 238 |
static const Word hiMask = RandomTraits<Word>::hiMask; |
| 239 | 239 |
|
| 240 | 240 |
current = state + length; |
| 241 | 241 |
|
| 242 | 242 |
register Word *curr = state + length - 1; |
| 243 | 243 |
register long num; |
| 244 | 244 |
|
| 245 | 245 |
num = length - shift; |
| 246 | 246 |
while (num--) {
|
| 247 | 247 |
curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^ |
| 248 | 248 |
curr[- shift] ^ mask[curr[-1] & 1ul]; |
| 249 | 249 |
--curr; |
| 250 | 250 |
} |
| 251 | 251 |
num = shift - 1; |
| 252 | 252 |
while (num--) {
|
| 253 | 253 |
curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^ |
| 254 | 254 |
curr[length - shift] ^ mask[curr[-1] & 1ul]; |
| 255 | 255 |
--curr; |
| 256 | 256 |
} |
| 257 |
|
|
| 257 |
state[0] = (((state[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^ |
|
| 258 | 258 |
curr[length - shift] ^ mask[curr[length - 1] & 1ul]; |
| 259 | 259 |
|
| 260 | 260 |
} |
| 261 | 261 |
|
| 262 | 262 |
|
| 263 | 263 |
Word *current; |
| 264 | 264 |
Word state[length]; |
| 265 | 265 |
|
| 266 | 266 |
}; |
| 267 | 267 |
|
| 268 | 268 |
|
| 269 | 269 |
template <typename Result, |
| 270 | 270 |
int shift = (std::numeric_limits<Result>::digits + 1) / 2> |
| 271 | 271 |
struct Masker {
|
| 272 | 272 |
static Result mask(const Result& result) {
|
| 273 | 273 |
return Masker<Result, (shift + 1) / 2>:: |
| 274 | 274 |
mask(static_cast<Result>(result | (result >> shift))); |
| 275 | 275 |
} |
| 276 | 276 |
}; |
| 277 | 277 |
|
| 278 | 278 |
template <typename Result> |
| 279 | 279 |
struct Masker<Result, 1> {
|
| 280 | 280 |
static Result mask(const Result& result) {
|
| 281 | 281 |
return static_cast<Result>(result | (result >> 1)); |
| 282 | 282 |
} |
| 283 | 283 |
}; |
| 284 | 284 |
|
| 285 | 285 |
template <typename Result, typename Word, |
| 286 | 286 |
int rest = std::numeric_limits<Result>::digits, int shift = 0, |
| 287 | 287 |
bool last = rest <= std::numeric_limits<Word>::digits> |
| 288 | 288 |
struct IntConversion {
|
| 289 | 289 |
static const int bits = std::numeric_limits<Word>::digits; |
| 290 | 290 |
|
| 291 | 291 |
static Result convert(RandomCore<Word>& rnd) {
|
| 292 | 292 |
return static_cast<Result>(rnd() >> (bits - rest)) << shift; |
| 293 | 293 |
} |
| 294 | 294 |
|
| 295 | 295 |
}; |
| 296 | 296 |
|
| 297 | 297 |
template <typename Result, typename Word, int rest, int shift> |
| 298 | 298 |
struct IntConversion<Result, Word, rest, shift, false> {
|
| 299 | 299 |
static const int bits = std::numeric_limits<Word>::digits; |
| 300 | 300 |
|
| 301 | 301 |
static Result convert(RandomCore<Word>& rnd) {
|
| 302 | 302 |
return (static_cast<Result>(rnd()) << shift) | |
| 303 | 303 |
IntConversion<Result, Word, rest - bits, shift + bits>::convert(rnd); |
| 304 | 304 |
} |
| 305 | 305 |
}; |
0 comments (0 inline)