1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef SkRandom_DEFINED 18 #define SkRandom_DEFINED 19 20 #include "Sk64.h" 21 #include "SkScalar.h" 22 23 /** \class SkRandom 24 25 Utility class that implements pseudo random 32bit numbers using a fast 26 linear equation. Unlike rand(), this class holds its own seed (initially 27 set to 0), so that multiple instances can be used with no side-effects. 28 */ 29 class SkRandom { 30 public: 31 SkRandom() : fSeed(0) {} 32 SkRandom(uint32_t seed) : fSeed(seed) {} 33 34 /** Return the next pseudo random number as an unsigned 32bit value. 35 */ 36 uint32_t nextU() { uint32_t r = fSeed * kMul + kAdd; fSeed = r; return r; } 37 38 /** Return the next pseudo random number as a signed 32bit value. 39 */ 40 int32_t nextS() { return (int32_t)this->nextU(); } 41 42 /** Return the next pseudo random number as an unsigned 16bit value. 43 */ 44 U16CPU nextU16() { return this->nextU() >> 16; } 45 46 /** Return the next pseudo random number as a signed 16bit value. 47 */ 48 S16CPU nextS16() { return this->nextS() >> 16; } 49 50 /** Return the next pseudo random number, as an unsigned value of 51 at most bitCount bits. 52 @param bitCount The maximum number of bits to be returned 53 */ 54 uint32_t nextBits(unsigned bitCount) { 55 SkASSERT(bitCount > 0 && bitCount <= 32); 56 return this->nextU() >> (32 - bitCount); 57 } 58 59 /** Return the next pseudo random unsigned number, mapped to lie within 60 [min, max] inclusive. 61 */ 62 uint32_t nextRangeU(uint32_t min, uint32_t max) { 63 SkASSERT(min <= max); 64 return min + this->nextU() % (max - min + 1); 65 } 66 67 /** Return the next pseudo random number expressed as an unsigned SkFixed 68 in the range [0..SK_Fixed1). 69 */ 70 SkFixed nextUFixed1() { return this->nextU() >> 16; } 71 72 /** Return the next pseudo random number expressed as a signed SkFixed 73 in the range (-SK_Fixed1..SK_Fixed1). 74 */ 75 SkFixed nextSFixed1() { return this->nextS() >> 15; } 76 77 /** Return the next pseudo random number expressed as a SkScalar 78 in the range [0..SK_Scalar1). 79 */ 80 SkScalar nextUScalar1() { return SkFixedToScalar(this->nextUFixed1()); } 81 82 /** Return the next pseudo random number expressed as a SkScalar 83 in the range (-SK_Scalar1..SK_Scalar1). 84 */ 85 SkScalar nextSScalar1() { return SkFixedToScalar(this->nextSFixed1()); } 86 87 /** Return the next pseudo random number as a signed 64bit value. 88 */ 89 void next64(Sk64* a) { 90 SkASSERT(a); 91 a->set(this->nextS(), this->nextU()); 92 } 93 94 /** Set the seed of the random object. The seed is initialized to 0 when the 95 object is first created, and is updated each time the next pseudo random 96 number is requested. 97 */ 98 void setSeed(int32_t seed) { fSeed = (uint32_t)seed; } 99 100 private: 101 // See "Numerical Recipes in C", 1992 page 284 for these constants 102 enum { 103 kMul = 1664525, 104 kAdd = 1013904223 105 }; 106 uint32_t fSeed; 107 }; 108 109 #endif 110 111