Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(690)

Unified Diff: base/rand_util.cc

Issue 5801: Reduce RandDouble to one call to ldexp, add one bit of precision (Closed) Base URL: svn://chrome-svn.corp.google.com/chrome/trunk/src/
Patch Set: '' Created 12 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | base/rand_util_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
}
« no previous file with comments | « no previous file | base/rand_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698