| Index: base/rand_util.cc
|
| ===================================================================
|
| --- base/rand_util.cc (revision 2710)
|
| +++ base/rand_util.cc (working copy)
|
| @@ -6,18 +6,11 @@
|
|
|
| #include <math.h>
|
|
|
| +#include <limits>
|
| +
|
| #include "base/basictypes.h"
|
| #include "base/logging.h"
|
|
|
| -namespace {
|
| -
|
| -union uint64_splitter {
|
| - uint64 normal;
|
| - uint16 split[4];
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| namespace base {
|
|
|
| int RandInt(int min, int max) {
|
| @@ -31,15 +24,15 @@
|
| }
|
|
|
| double RandDouble() {
|
| - uint64_splitter number;
|
| - number.normal = base::RandUInt64();
|
| + // We try to get maximum precision by masking out as many bits as will fit
|
| + // in the target type's mantissa, and raising it to an appropriate power to
|
| + // produce output in the range [0, 1). For IEEE 754 doubles, the mantissa
|
| + // is expected to accommodate 53 bits.
|
|
|
| - // Standard code based on drand48 would give only 48 bits of precision.
|
| - // We try to get maximum precision for IEEE 754 double (52 bits).
|
| - double result = ldexp(static_cast<double>(number.split[0] & 0xf), -52) +
|
| - ldexp(static_cast<double>(number.split[1]), -48) +
|
| - ldexp(static_cast<double>(number.split[2]), -32) +
|
| - ldexp(static_cast<double>(number.split[3]), -16);
|
| + COMPILE_ASSERT(std::numeric_limits<double>::radix == 2, otherwise_use_scalbn);
|
| + static const int kBits = std::numeric_limits<double>::digits;
|
| + uint64 random_bits = base::RandUInt64() & ((GG_UINT64_C(1) << kBits) - 1);
|
| + double result = ldexp(static_cast<double>(random_bits), -1 * kBits);
|
| DCHECK(result >= 0.0 && result < 1.0);
|
| return result;
|
| }
|
|
|