1 /* 2 * Copyright (C) 2017 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 18 #ifndef ANALYZER_PSEUDORANDOM_H 19 #define ANALYZER_PSEUDORANDOM_H 20 21 #include <cctype> 22 23 class PseudoRandom { 24 public: 25 PseudoRandom(int64_t seed = 99887766) mSeed(seed)26 : mSeed(seed) 27 {} 28 29 /** 30 * Returns the next random double from -1.0 to 1.0 31 * 32 * @return value from -1.0 to 1.0 33 */ nextRandomDouble()34 double nextRandomDouble() { 35 return nextRandomInteger() * (0.5 / (((int32_t)1) << 30)); 36 } 37 38 /** Calculate random 32 bit number using linear-congruential method 39 * with known real-time performance. 40 */ nextRandomInteger()41 int32_t nextRandomInteger() { 42 #if __has_builtin(__builtin_mul_overflow) && __has_builtin(__builtin_add_overflow) 43 int64_t prod; 44 // Use values for 64-bit sequence from MMIX by Donald Knuth. 45 __builtin_mul_overflow(mSeed, (int64_t)6364136223846793005, &prod); 46 __builtin_add_overflow(prod, (int64_t)1442695040888963407, &mSeed); 47 #else 48 mSeed = (mSeed * (int64_t)6364136223846793005) + (int64_t)1442695040888963407; 49 #endif 50 return (int32_t) (mSeed >> 32); // The higher bits have a longer sequence. 51 } 52 53 private: 54 int64_t mSeed; 55 }; 56 57 #endif //ANALYZER_PSEUDORANDOM_H 58