OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/rand_util.h" | 5 #include "base/rand_util.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
| 8 #include <vector> |
8 | 9 |
9 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
10 | 11 |
11 namespace { | 12 namespace { |
12 | 13 |
13 const int kIntMin = std::numeric_limits<int>::min(); | 14 const int kIntMin = std::numeric_limits<int>::min(); |
14 const int kIntMax = std::numeric_limits<int>::max(); | 15 const int kIntMax = std::numeric_limits<int>::max(); |
15 | 16 |
16 } // namespace | 17 } // namespace |
17 | 18 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 EXPECT_NE(0, accumulator); | 55 EXPECT_NE(0, accumulator); |
55 } | 56 } |
56 | 57 |
57 // Make sure that it is still appropriate to use RandGenerator in conjunction | 58 // Make sure that it is still appropriate to use RandGenerator in conjunction |
58 // with std::random_shuffle(). | 59 // with std::random_shuffle(). |
59 TEST(RandUtilTest, RandGeneratorForRandomShuffle) { | 60 TEST(RandUtilTest, RandGeneratorForRandomShuffle) { |
60 EXPECT_EQ(base::RandGenerator(1), 0U); | 61 EXPECT_EQ(base::RandGenerator(1), 0U); |
61 EXPECT_LE(std::numeric_limits<ptrdiff_t>::max(), | 62 EXPECT_LE(std::numeric_limits<ptrdiff_t>::max(), |
62 std::numeric_limits<int64>::max()); | 63 std::numeric_limits<int64>::max()); |
63 } | 64 } |
| 65 |
| 66 TEST(RandUtilTest, RandGeneratorIsUniform) { |
| 67 // Verify that RandGenerator has a uniform distribution. This is a |
| 68 // regression test that consistently failed when RandGenerator was |
| 69 // implemented this way: |
| 70 // |
| 71 // return base::RandUint64() % max; |
| 72 // |
| 73 // A degenerate case for such an implementation is e.g. a top of |
| 74 // range that is 2/3rds of the way to MAX_UINT64, in which case the |
| 75 // bottom half of the range would be twice as likely to occur as the |
| 76 // top half. A bit of calculus care of jar@ shows that the largest |
| 77 // measurable delta is when the top of the range is 3/4ths of the |
| 78 // way, so that's what we use in the test. |
| 79 const uint64 kTopOfRange = (std::numeric_limits<uint64>::max() / 4ULL) * 3ULL; |
| 80 const uint64 kExpectedAverage = kTopOfRange / 2ULL; |
| 81 const uint64 kAllowedVariance = kExpectedAverage / 50ULL; // +/- 2% |
| 82 const int kMinAttempts = 1000; |
| 83 const int kMaxAttempts = 1000000; |
| 84 |
| 85 double cumulative_average = 0.0; |
| 86 int count = 0; |
| 87 while (count < kMaxAttempts) { |
| 88 uint64 value = base::RandGenerator(kTopOfRange); |
| 89 cumulative_average = (count * cumulative_average + value) / (count + 1); |
| 90 |
| 91 // Don't quit too quickly for things to start converging, or we may have |
| 92 // a false positive. |
| 93 if (count > kMinAttempts && |
| 94 kExpectedAverage - kAllowedVariance < cumulative_average && |
| 95 cumulative_average < kExpectedAverage + kAllowedVariance) { |
| 96 break; |
| 97 } |
| 98 |
| 99 ++count; |
| 100 } |
| 101 |
| 102 ASSERT_LT(count, kMaxAttempts) << "Expected average was " << |
| 103 kExpectedAverage << ", average ended at " << cumulative_average; |
| 104 } |
| 105 |
| 106 TEST(RandUtilTest, RandUint64ProducesBothValuesOfAllBits) { |
| 107 // This tests to see that our underlying random generator is good |
| 108 // enough, for some value of good enough. |
| 109 uint64 kAllZeros = 0ULL; |
| 110 uint64 kAllOnes = ~kAllZeros; |
| 111 uint64 found_ones = kAllZeros; |
| 112 uint64 found_zeros = kAllOnes; |
| 113 |
| 114 for (size_t i = 0; i < 1000; ++i) { |
| 115 uint64 value = base::RandUint64(); |
| 116 found_ones |= value; |
| 117 found_zeros &= value; |
| 118 |
| 119 if (found_zeros == kAllZeros && found_ones == kAllOnes) |
| 120 return; |
| 121 } |
| 122 |
| 123 FAIL() << "Didn't achieve all bit values in maximum number of tries."; |
| 124 } |
OLD | NEW |