/*------------------------------------------------------------------------- * drawElements Base Portability Library * ------------------------------------- * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Random number generation. *//*--------------------------------------------------------------------*/ #include "deRandom.h" #include <float.h> #include <math.h> DE_BEGIN_EXTERN_C /*--------------------------------------------------------------------*//*! * \brief Initialize a random number generator with a given seed. * \param rnd RNG to initialize. * \param seed Seed value used for random values. *//*--------------------------------------------------------------------*/ void deRandom_init (deRandom* rnd, deUint32 seed) { rnd->x = (deUint32)(-(int)seed ^ 123456789); rnd->y = (deUint32)(362436069 * seed); rnd->z = (deUint32)(521288629 ^ (seed >> 7)); rnd->w = (deUint32)(88675123 ^ (seed << 3)); } /*--------------------------------------------------------------------*//*! * \brief Get a pseudo random uint32. * \param rnd Pointer to RNG. * \return Random uint32 number. *//*--------------------------------------------------------------------*/ deUint32 deRandom_getUint32 (deRandom* rnd) { deUint32 w = rnd->w; deUint32 t; t = rnd->x ^ (rnd->x << 11); rnd->x = rnd->y; rnd->y = rnd->z; rnd->z = w; rnd->w = w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)); return w; } /*--------------------------------------------------------------------*//*! * \brief Get a pseudo random uint64. * \param rnd Pointer to RNG. * \return Random uint64 number. *//*--------------------------------------------------------------------*/ deUint64 deRandom_getUint64 (deRandom* rnd) { deUint64 x = deRandom_getUint32(rnd); return x << 32 | deRandom_getUint32(rnd); } /*--------------------------------------------------------------------*//*! * \brief Get a pseudo random float in range [0, 1[. * \param rnd Pointer to RNG. * \return Random float number. *//*--------------------------------------------------------------------*/ float deRandom_getFloat (deRandom* rnd) { return (float)(deRandom_getUint32(rnd) & 0xFFFFFFFu) / (float)(0xFFFFFFFu+1); } /*--------------------------------------------------------------------*//*! * \brief Get a pseudo random float in range [0, 1[. * \param rnd Pointer to RNG. * \return Random float number. *//*--------------------------------------------------------------------*/ double deRandom_getDouble (deRandom* rnd) { DE_STATIC_ASSERT(FLT_RADIX == 2); return ldexp((double)(deRandom_getUint64(rnd) & ((1ull << DBL_MANT_DIG) - 1)), -DBL_MANT_DIG); } /*--------------------------------------------------------------------*//*! * \brief Get a pseudo random boolean value (DE_FALSE or DE_TRUE). * \param rnd Pointer to RNG. * \return Random float number. *//*--------------------------------------------------------------------*/ deBool deRandom_getBool (deRandom* rnd) { deUint32 val = deRandom_getUint32(rnd); return ((val & 0xFFFFFF) < 0x800000); } DE_END_EXTERN_C