range [0, 1.0) This uses a technique described by Saito and Matsumoto at MCQMC'08. Given that the IEEE floating point numbers are uniformly distributed over [1,2), we generate a number in this range and then offset it onto the range [0,1). The choice of bits (masking v. shifting) is arbitrary and should be immaterial for high quality generators.
| 406 | // choice of bits (masking v. shifting) is arbitrary and |
| 407 | // should be immaterial for high quality generators. |
| 408 | double random_real() |
| 409 | { |
| 410 | static const uint64_t UPPER_BITS = 0x3FF0000000000000ULL; |
| 411 | static const uint64_t LOWER_MASK = 0x000FFFFFFFFFFFFFULL; |
| 412 | const uint64_t value = UPPER_BITS | (rng::get_uint64() & LOWER_MASK); |
| 413 | double result; |
| 414 | // Portable memory transmutation. The union trick almost always |
| 415 | // works, but this is safer. |
| 416 | memcpy(&result, &value, sizeof(value)); |
| 417 | return result - 1.0; |
| 418 | } |
| 419 | |
| 420 | // Roll n_trials, return true if at least one succeeded. n_trials might be |
| 421 | // not integer. |
no test coverage detected