1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/rand_util.h"
11 #include "base/basictypes.h"
12 #include "base/logging.h"
13 #include "base/string_util.h"
17 int RandInt(int min
, int max
) {
20 uint64 range
= static_cast<uint64
>(max
) - min
+ 1;
21 int result
= min
+ static_cast<int>(base::RandGenerator(range
));
22 DCHECK_GE(result
, min
);
23 DCHECK_LE(result
, max
);
28 return BitsToOpenEndedUnitInterval(base::RandUint64());
31 double BitsToOpenEndedUnitInterval(uint64 bits
) {
32 // We try to get maximum precision by masking out as many bits as will fit
33 // in the target type's mantissa, and raising it to an appropriate power to
34 // produce output in the range [0, 1). For IEEE 754 doubles, the mantissa
35 // is expected to accommodate 53 bits.
37 COMPILE_ASSERT(std::numeric_limits
<double>::radix
== 2, otherwise_use_scalbn
);
38 static const int kBits
= std::numeric_limits
<double>::digits
;
39 uint64 random_bits
= bits
& ((GG_UINT64_C(1) << kBits
) - 1);
40 double result
= ldexp(static_cast<double>(random_bits
), -1 * kBits
);
41 DCHECK_GE(result
, 0.0);
42 DCHECK_LT(result
, 1.0);
46 uint64
RandGenerator(uint64 range
) {
48 // We must discard random results above this number, as they would
49 // make the random generator non-uniform (consider e.g. if
50 // MAX_UINT64 was 7 and |range| was 5, then a result of 1 would be twice
51 // as likely as a result of 3 or 4).
52 uint64 max_acceptable_value
=
53 (std::numeric_limits
<uint64
>::max() / range
) * range
- 1;
57 value
= base::RandUint64();
58 } while (value
> max_acceptable_value
);
63 void RandBytes(void* output
, size_t output_length
) {
65 size_t random_int_size
= sizeof(random_int
);
66 for (size_t i
= 0; i
< output_length
; i
+= random_int_size
) {
67 random_int
= base::RandUint64();
68 size_t copy_count
= std::min(output_length
- i
, random_int_size
);
69 memcpy(((uint8
*)output
) + i
, &random_int
, copy_count
);
73 std::string
RandBytesAsString(size_t length
) {
75 RandBytes(WriteInto(&result
, length
+ 1), length
);