| /*------------------------------------------------------------------------- |
| * 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 |