Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #ifndef WEBRTC_BASE_RANDOM_H_
     12 #define WEBRTC_BASE_RANDOM_H_
     13 
     14 #include <limits>
     15 
     16 #include "webrtc/typedefs.h"
     17 #include "webrtc/base/constructormagic.h"
     18 #include "webrtc/base/checks.h"
     19 
     20 namespace webrtc {
     21 
     22 class Random {
     23  public:
     24   explicit Random(uint64_t seed);
     25 
     26   // Return pseudo-random integer of the specified type.
     27   // We need to limit the size to 32 bits to keep the output close to uniform.
     28   template <typename T>
     29   T Rand() {
     30     static_assert(std::numeric_limits<T>::is_integer &&
     31                       std::numeric_limits<T>::radix == 2 &&
     32                       std::numeric_limits<T>::digits <= 32,
     33                   "Rand is only supported for built-in integer types that are "
     34                   "32 bits or smaller.");
     35     return static_cast<T>(NextOutput());
     36   }
     37 
     38   // Uniformly distributed pseudo-random number in the interval [0, t].
     39   uint32_t Rand(uint32_t t);
     40 
     41   // Uniformly distributed pseudo-random number in the interval [low, high].
     42   uint32_t Rand(uint32_t low, uint32_t high);
     43 
     44   // Uniformly distributed pseudo-random number in the interval [low, high].
     45   int32_t Rand(int32_t low, int32_t high);
     46 
     47   // Normal Distribution.
     48   double Gaussian(double mean, double standard_deviation);
     49 
     50   // Exponential Distribution.
     51   double Exponential(double lambda);
     52 
     53  private:
     54   // Outputs a nonzero 64-bit random number.
     55   uint64_t NextOutput() {
     56     state_ ^= state_ >> 12;
     57     state_ ^= state_ << 25;
     58     state_ ^= state_ >> 27;
     59     RTC_DCHECK(state_ != 0x0ULL);
     60     return state_ * 2685821657736338717ull;
     61   }
     62 
     63   uint64_t state_;
     64 
     65   RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Random);
     66 };
     67 
     68 // Return pseudo-random number in the interval [0.0, 1.0).
     69 template <>
     70 float Random::Rand<float>();
     71 
     72 // Return pseudo-random number in the interval [0.0, 1.0).
     73 template <>
     74 double Random::Rand<double>();
     75 
     76 // Return pseudo-random boolean value.
     77 template <>
     78 bool Random::Rand<bool>();
     79 
     80 }  // namespace webrtc
     81 
     82 #endif  // WEBRTC_BASE_RANDOM_H_
     83