Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2006 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef SkRandom_DEFINED
     11 #define SkRandom_DEFINED
     12 
     13 #include "Sk64.h"
     14 #include "SkScalar.h"
     15 
     16 /** \class SkRandom
     17 
     18     Utility class that implements pseudo random 32bit numbers using a fast
     19     linear equation. Unlike rand(), this class holds its own seed (initially
     20     set to 0), so that multiple instances can be used with no side-effects.
     21 */
     22 class SkRandom {
     23 public:
     24     SkRandom() : fSeed(0) {}
     25     SkRandom(uint32_t seed) : fSeed(seed) {}
     26 
     27     /** Return the next pseudo random number as an unsigned 32bit value.
     28     */
     29     uint32_t nextU() { uint32_t r = fSeed * kMul + kAdd; fSeed = r; return r; }
     30 
     31     /** Return the next pseudo random number as a signed 32bit value.
     32     */
     33     int32_t nextS() { return (int32_t)this->nextU(); }
     34 
     35     /** Return the next pseudo random number as an unsigned 16bit value.
     36     */
     37     U16CPU nextU16() { return this->nextU() >> 16; }
     38 
     39     /** Return the next pseudo random number as a signed 16bit value.
     40     */
     41     S16CPU nextS16() { return this->nextS() >> 16; }
     42 
     43     /** Return the next pseudo random number, as an unsigned value of
     44         at most bitCount bits.
     45         @param bitCount The maximum number of bits to be returned
     46     */
     47     uint32_t nextBits(unsigned bitCount) {
     48         SkASSERT(bitCount > 0 && bitCount <= 32);
     49         return this->nextU() >> (32 - bitCount);
     50     }
     51 
     52     /** Return the next pseudo random unsigned number, mapped to lie within
     53         [min, max] inclusive.
     54     */
     55     uint32_t nextRangeU(uint32_t min, uint32_t max) {
     56         SkASSERT(min <= max);
     57         return min + this->nextU() % (max - min + 1);
     58     }
     59 
     60     /** Return the next pseudo random number expressed as an unsigned SkFixed
     61         in the range [0..SK_Fixed1).
     62     */
     63     SkFixed nextUFixed1() { return this->nextU() >> 16; }
     64 
     65     /** Return the next pseudo random number expressed as a signed SkFixed
     66         in the range (-SK_Fixed1..SK_Fixed1).
     67     */
     68     SkFixed nextSFixed1() { return this->nextS() >> 15; }
     69 
     70     /** Return the next pseudo random number expressed as a SkScalar
     71         in the range [0..SK_Scalar1).
     72     */
     73     SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); }
     74 
     75     /** Return the next pseudo random number expressed as a SkScalar
     76         in the range (-SK_Scalar1..SK_Scalar1).
     77     */
     78     SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); }
     79 
     80     /** Return the next pseudo random number as a signed 64bit value.
     81     */
     82     void next64(Sk64* a) {
     83         SkASSERT(a);
     84         a->set(this->nextS(), this->nextU());
     85     }
     86 
     87     /** Set the seed of the random object. The seed is initialized to 0 when the
     88         object is first created, and is updated each time the next pseudo random
     89         number is requested.
     90     */
     91     void setSeed(int32_t seed) { fSeed = (uint32_t)seed; }
     92 
     93 private:
     94     //  See "Numerical Recipes in C", 1992 page 284 for these constants
     95     enum {
     96         kMul = 1664525,
     97         kAdd = 1013904223
     98     };
     99     uint32_t fSeed;
    100 };
    101 
    102 #endif
    103 
    104