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: SkRandom()24 SkRandom() : fSeed(0) {} SkRandom(uint32_t seed)25 SkRandom(uint32_t seed) : fSeed(seed) {} 26 27 /** Return the next pseudo random number as an unsigned 32bit value. 28 */ nextU()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 */ nextS()33 int32_t nextS() { return (int32_t)this->nextU(); } 34 35 /** Return the next pseudo random number as an unsigned 16bit value. 36 */ nextU16()37 U16CPU nextU16() { return this->nextU() >> 16; } 38 39 /** Return the next pseudo random number as a signed 16bit value. 40 */ nextS16()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 */ nextBits(unsigned bitCount)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 */ nextRangeU(uint32_t min,uint32_t max)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 */ nextUFixed1()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 */ nextSFixed1()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 */ nextUScalar1()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 */ nextSScalar1()78 SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); } 79 80 /** Return the next pseudo random number as a signed 64bit value. 81 */ next64(Sk64 * a)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 */ setSeed(int32_t seed)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