Home | History | Annotate | Download | only in debase
      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  *//*--------------------------------------------------------------------*/
     36 void 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  *//*--------------------------------------------------------------------*/
     49 deUint32 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  *//*--------------------------------------------------------------------*/
     67 deUint64 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  *//*--------------------------------------------------------------------*/
     78 float 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  *//*--------------------------------------------------------------------*/
     88 double 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  *//*--------------------------------------------------------------------*/
    100 deBool deRandom_getBool (deRandom* rnd)
    101 {
    102 	deUint32 val = deRandom_getUint32(rnd);
    103 	return ((val & 0xFFFFFF) < 0x800000);
    104 }
    105 
    106 DE_END_EXTERN_C
    107