summaryrefslogtreecommitdiffstats
path: root/base/rand_util.cc
diff options
context:
space:
mode:
authormark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-30 14:26:33 +0000
committermark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-30 14:26:33 +0000
commit94a0f313c3770201516f9a8a9c342c250d9fe915 (patch)
tree3419864fadbbf18c358c0ae104b1d45171b42422 /base/rand_util.cc
parent44fd14c5ade3ff22063382c63409ba18bcb5d50a (diff)
downloadchromium_src-94a0f313c3770201516f9a8a9c342c250d9fe915.zip
chromium_src-94a0f313c3770201516f9a8a9c342c250d9fe915.tar.gz
chromium_src-94a0f313c3770201516f9a8a9c342c250d9fe915.tar.bz2
Reduce RandDouble to one call to ldexp, add one bit of precision
Review URL: http://codereview.chromium.org/5801 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2712 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/rand_util.cc')
-rw-r--r--base/rand_util.cc29
1 files changed, 11 insertions, 18 deletions
diff --git a/base/rand_util.cc b/base/rand_util.cc
index 89b5b32..cefc7bb 100644
--- a/base/rand_util.cc
+++ b/base/rand_util.cc
@@ -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 @@ int RandInt(int min, int max) {
}
double RandDouble() {
- uint64_splitter number;
- number.normal = base::RandUInt64();
-
- // 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);
+ // 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.
+
+ 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;
}