1 /*------------------------------------------------------------------------- 2 * drawElements Base Portability Library 3 * ------------------------------------- 4 * 5 * Copyright 2014 The Android Open Source Project 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Random number generation. 22 *//*--------------------------------------------------------------------*/ 23 24 #include "deRandom.h" 25 26 #include <float.h> 27 #include <math.h> 28 29 DE_BEGIN_EXTERN_C 30 31 /*--------------------------------------------------------------------*//*! 32 * \brief Initialize a random number generator with a given seed. 33 * \param rnd RNG to initialize. 34 * \param seed Seed value used for random values. 35 *//*--------------------------------------------------------------------*/ deRandom_init(deRandom * rnd,deUint32 seed)36void deRandom_init (deRandom* rnd, deUint32 seed) 37 { 38 rnd->x = (deUint32)(-(int)seed ^ 123456789); 39 rnd->y = (deUint32)(362436069 * seed); 40 rnd->z = (deUint32)(521288629 ^ (seed >> 7)); 41 rnd->w = (deUint32)(88675123 ^ (seed << 3)); 42 } 43 44 /*--------------------------------------------------------------------*//*! 45 * \brief Get a pseudo random uint32. 46 * \param rnd Pointer to RNG. 47 * \return Random uint32 number. 48 *//*--------------------------------------------------------------------*/ deRandom_getUint32(deRandom * rnd)49deUint32 deRandom_getUint32 (deRandom* rnd) 50 { 51 deUint32 w = rnd->w; 52 deUint32 t; 53 54 t = rnd->x ^ (rnd->x << 11); 55 rnd->x = rnd->y; 56 rnd->y = rnd->z; 57 rnd->z = w; 58 rnd->w = w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)); 59 return w; 60 } 61 62 /*--------------------------------------------------------------------*//*! 63 * \brief Get a pseudo random uint64. 64 * \param rnd Pointer to RNG. 65 * \return Random uint64 number. 66 *//*--------------------------------------------------------------------*/ deRandom_getUint64(deRandom * rnd)67deUint64 deRandom_getUint64 (deRandom* rnd) 68 { 69 deUint64 x = deRandom_getUint32(rnd); 70 return x << 32 | deRandom_getUint32(rnd); 71 } 72 73 /*--------------------------------------------------------------------*//*! 74 * \brief Get a pseudo random float in range [0, 1[. 75 * \param rnd Pointer to RNG. 76 * \return Random float number. 77 *//*--------------------------------------------------------------------*/ deRandom_getFloat(deRandom * rnd)78float deRandom_getFloat (deRandom* rnd) 79 { 80 return (float)(deRandom_getUint32(rnd) & 0xFFFFFFFu) / (float)(0xFFFFFFFu+1); 81 } 82 83 /*--------------------------------------------------------------------*//*! 84 * \brief Get a pseudo random float in range [0, 1[. 85 * \param rnd Pointer to RNG. 86 * \return Random float number. 87 *//*--------------------------------------------------------------------*/ deRandom_getDouble(deRandom * rnd)88double deRandom_getDouble (deRandom* rnd) 89 { 90 DE_STATIC_ASSERT(FLT_RADIX == 2); 91 return ldexp((double)(deRandom_getUint64(rnd) & ((1ull << DBL_MANT_DIG) - 1)), 92 -DBL_MANT_DIG); 93 } 94 95 /*--------------------------------------------------------------------*//*! 96 * \brief Get a pseudo random boolean value (DE_FALSE or DE_TRUE). 97 * \param rnd Pointer to RNG. 98 * \return Random float number. 99 *//*--------------------------------------------------------------------*/ deRandom_getBool(deRandom * rnd)100deBool deRandom_getBool (deRandom* rnd) 101 { 102 deUint32 val = deRandom_getUint32(rnd); 103 return ((val & 0xFFFFFF) < 0x800000); 104 } 105 106 DE_END_EXTERN_C 107